home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / util / gnu / a2_0b_Emacs_sr.lha / Emacs-19.25 / site-lisp / cc-mode.el < prev    next >
Lisp/Scheme  |  1994-09-10  |  155KB  |  4,261 lines

  1. ;;; cc-mode.el --- major mode for editing C++ and C code
  2.  
  3. ;; Authors: 1992 Barry A. Warsaw <bwarsaw@cnri.reston.va.us>
  4. ;;          1987 Dave Detlefs and Stewart Clamen
  5. ;;          1985 Richard M. Stallman
  6. ;; Maintainer: cc-mode-help@anthem.nlm.nih.gov
  7. ;; Created: a long, long, time ago. adapted from the original c-mode.el
  8. ;; Version:         4.85
  9. ;; Last Modified:   1994/09/08 14:27:45
  10. ;; Keywords: C++ C Objective-C editing major-mode
  11.  
  12. ;; Copyright (C) 1992, 1993, 1994 Barry A. Warsaw
  13. ;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
  14.  
  15. ;; This file is part of GNU Emacs.
  16.  
  17. ;; GNU Emacs is free software; you can redistribute it and/or modify
  18. ;; it under the terms of the GNU General Public License as published by
  19. ;; the Free Software Foundation; either version 2, or (at your option)
  20. ;; any later version.
  21.  
  22. ;; GNU Emacs is distributed in the hope that it will be useful,
  23. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. ;; GNU General Public License for more details.
  26.  
  27. ;; You should have received a copy of the GNU General Public License
  28. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  29. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  
  31. ;;; Commentary:
  32.  
  33. ;; This package provides modes in GNU Emacs for editing C, C++, and
  34. ;; Objective-C code. It is intended to be a replacement for c-mode.el
  35. ;; (a.k.a. BOCM -- Boring Old C-Mode), and c++-mode.el, both of which
  36. ;; are ancestors of this file.  A number of important improvements
  37. ;; have been made, briefly: complete K&R C, ANSI C, `ARM' C++, and
  38. ;; Objective-C support with consistent indentation across all modes,
  39. ;; more intuitive indentation controlling variables, compatibility
  40. ;; across all known Emacsen, nice new features, and tons of bug fixes.
  41. ;; This package is called "cc-mode" to distinguish it from its
  42. ;; ancestors, but there really is no top-level cc-mode.
  43.  
  44. ;; Details on how to use cc-mode will some day be contained in an
  45. ;; accompanying texinfo manual.  Volunteers to help finish this manual
  46. ;; would be greatly appreciated!  Contact me at the address above if
  47. ;; you'd like to volunteer. Until the manual is finished, an
  48. ;; accompanying README is the only documentation available.
  49.  
  50. ;; To submit bug reports, hit "C-c C-b", and please try to include a
  51. ;; code sample and exact recipe so I can reproduce your problem.  If
  52. ;; you have other questions contact me at the following address:
  53. ;; cc-mode-help@anthem.nlm.nih.gov.  Please don't send bug reports to
  54. ;; my personal account, I may not get it for a long time.
  55.  
  56. ;; YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS. They are the result of
  57. ;; the multi-Emacsen support. FSF's Emacs 19, XEmacs 19 (formerly
  58. ;; Lucid), and GNU Emacs 18 all do things differently and there's no
  59. ;; way to shut the byte-compiler up at the necessary granularity.  Let
  60. ;; me say this again: YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS (you'd
  61. ;; be surprised at how many people don't follow this advice :-).
  62.  
  63. ;; If your Emacs is dumped with c-mode.el and/or c++-mode.el, you will
  64. ;; need to add the following to your .emacs file before any other
  65. ;; reference to c-mode or c++-mode:
  66. ;;
  67. ;; (fmakunbound 'c-mode)
  68. ;; (makunbound 'c-mode-map)
  69. ;; (fmakunbound 'c++-mode)
  70. ;; (makunbound 'c++-mode-map)
  71. ;; (makunbound 'c-style-alist)
  72.  
  73. ;; There are three major mode entry points provided by this package,
  74. ;; one for editing C++ code, one for editing C code (both K&R and
  75. ;; ANSI), and one for editing Objective-C code.  To use cc-mode, add
  76. ;; the following to your .emacs file.  This assumes you will use .cc
  77. ;; or .C extensions for your C++ source, .c for your C code, and .m
  78. ;; for your Objective-C code:
  79. ;;
  80. ;; (autoload 'c++-mode  "cc-mode" "C++ Editing Mode" t)
  81. ;; (autoload 'c-mode    "cc-mode" "C Editing Mode" t)
  82. ;; (autoload 'objc-mode "cc-mode" "Objective-C Editing Mode" t)
  83. ;; (setq auto-mode-alist
  84. ;;   (append '(("\\.C$"  . c++-mode)
  85. ;;             ("\\.cc$" . c++-mode)
  86. ;;             ("\\.c$"  . c-mode)
  87. ;;             ("\\.h$"  . c-mode)
  88. ;;             ("\\.m$"  . objc-mode)
  89. ;;            ) auto-mode-alist))
  90. ;;
  91. ;; If you would like to join the beta testers list, send add/drop
  92. ;; requests to cc-mode-victims-request@anthem.nlm.nih.gov.
  93. ;; Discussions go to cc-mode-victims@anthem.nlm.nih.gov, but bug
  94. ;; reports and such should still be sent to cc-mode-help only (see
  95. ;; above).
  96. ;;
  97. ;; Many, many thanks go out to all the folks on the beta test list.
  98. ;; Without their patience, testing, insight, code contributions, and
  99. ;; encouragement cc-mode.el would be a far inferior package.
  100.  
  101. ;; LCD Archive Entry:
  102. ;; cc-mode.el|Barry A. Warsaw|cc-mode-help@anthem.nlm.nih.gov
  103. ;; |Major mode for editing C++, Objective-C, and ANSI/K&R C code
  104. ;; |1994/09/08 14:27:45|4.85|
  105.  
  106. ;;; Code:
  107.  
  108.  
  109. ;; user definable variables
  110. ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  111.  
  112. (defvar c-inhibit-startup-warnings-p nil
  113.   "*If non-nil, inhibits start up compatibility warnings.")
  114. (defvar c-strict-syntax-p nil
  115.   "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
  116. If the syntactic symbol for a particular line does not match a symbol
  117. in the offsets alist, an error is generated, otherwise no error is
  118. reported and the syntactic symbol is ignored.")
  119. (defvar c-echo-syntactic-information-p nil
  120.   "*If non-nil, syntactic info is echoed when the line is indented.")
  121. (defvar c-basic-offset 4
  122.   "*Amount of basic offset used by + and - symbols in `c-offsets-alist'.")
  123.  
  124. (defconst c-offsets-alist-default
  125.   '((string                . -1000)
  126.     (c                     . c-lineup-C-comments)
  127.     (defun-open            . 0)
  128.     (defun-close           . 0)
  129.     (defun-block-intro     . +)
  130.     (class-open            . 0)
  131.     (class-close           . 0)
  132.     (inline-open           . +)
  133.     (inline-close          . 0)
  134.     (ansi-funcdecl-cont    . -)
  135.     (knr-argdecl-intro     . +)
  136.     (knr-argdecl           . 0)
  137.     (topmost-intro         . 0)
  138.     (topmost-intro-cont    . 0)
  139.     (member-init-intro     . +)
  140.     (member-init-cont      . 0)
  141.     (inher-intro           . +)
  142.     (inher-cont            . c-lineup-multi-inher)
  143.     (block-open            . 0)
  144.     (block-close           . 0)
  145.     (brace-list-open       . 0)
  146.     (brace-list-close      . 0)
  147.     (brace-list-intro      . +)
  148.     (brace-list-entry      . 0)
  149.     (statement             . 0)
  150.     ;; some people might prefer
  151.     ;;(statement             . c-lineup-runin-statements)
  152.     (statement-cont        . +)
  153.     ;; some people might prefer
  154.     ;;(statement-cont        . c-lineup-math)
  155.     (statement-block-intro . +)
  156.     (statement-case-intro  . +)
  157.     (statement-case-open   . 0)
  158.     (substatement          . +)
  159.     (substatement-open     . +)
  160.     (case-label            . 0)
  161.     (access-label          . -)
  162.     (label                 . 2)
  163.     (do-while-closure      . 0)
  164.     (else-clause           . 0)
  165.     (comment-intro         . c-lineup-comment)
  166.     (arglist-intro         . +)
  167.     (arglist-cont          . 0)
  168.     (arglist-cont-nonempty . c-lineup-arglist)
  169.     (arglist-close         . +)
  170.     (stream-op             . c-lineup-streamop)
  171.     (inclass               . +)
  172.     (cpp-macro             . -1000)
  173.     (friend                . 0)
  174.     (objc-method-intro     . -1000)
  175.     (objc-method-args-cont . c-lineup-objc-method-args)
  176.     (objc-method-call-cont . c-lineup-objc-method-call)
  177.     )
  178.   "Default settings for offsets of syntactic elements.
  179. Do not change this constant!  See the variable `c-offsets-alist' for
  180. more information.")
  181.  
  182. (defvar c-offsets-alist (copy-alist c-offsets-alist-default)
  183.   "*Association list of syntactic element symbols and indentation offsets.
  184. As described below, each cons cell in this list has the form:
  185.  
  186.     (SYNTACTIC-SYMBOL . OFFSET)
  187.  
  188. When a line is indented, cc-mode first determines the syntactic
  189. context of the line by generating a list of symbols called syntactic
  190. elements.  This list can contain more than one syntactic element and
  191. the global variable `c-syntactic-context' contains the context list
  192. for the line being indented.  Each element in this list is actually a
  193. cons cell of the syntactic symbol and a buffer position.  This buffer
  194. position is call the relative indent point for the line.  Some
  195. syntactic symbols may not have a relative indent point associated with
  196. them.
  197.  
  198. After the syntactic context list for a line is generated, cc-mode
  199. calculates the absolute indentation for the line by looking at each
  200. syntactic element in the list.  First, it compares the syntactic
  201. element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'.  When it
  202. finds a match, it adds the OFFSET to the column of the relative indent
  203. point.  The sum of this calculation for each element in the syntactic
  204. list is the absolute offset for line being indented.
  205.  
  206. If the syntactic element does not match any in the `c-offsets-alist',
  207. an error is generated if `c-strict-syntax-p' is non-nil, otherwise
  208. the element is ignored.
  209.  
  210. Actually, OFFSET can be an integer, a function, a variable, or one of
  211. the following symbols: `+', `-', `++', or `--'.  These latter
  212. designate positive or negative multiples of `c-basic-offset',
  213. respectively: *1, *-1, *2, and *-2. If OFFSET is a function, it is
  214. called with a single argument containing the cons of the syntactic
  215. element symbol and the relative indent point.  The function should
  216. return an integer offset.
  217.  
  218. Here is the current list of valid syntactic element symbols:
  219.  
  220.  string                 -- inside multi-line string
  221.  c                      -- inside a multi-line C style block comment
  222.  defun-open             -- brace that opens a function definition
  223.  defun-close            -- brace that closes a function definition
  224.  defun-block-intro      -- the first line in a top-level defun
  225.  class-open             -- brace that opens a class definition
  226.  class-close            -- brace that closes a class definition
  227.  inline-open            -- brace that opens an in-class inline method
  228.  inline-close           -- brace that closes an in-class inline method
  229.  ansi-funcdecl-cont     -- the nether region between an ANSI function
  230.                            declaration and the defun opening brace
  231.  knr-argdecl-intro      -- first line of a K&R C argument declaration
  232.  knr-argdecl            -- subsequent lines in a K&R C argument declaration
  233.  topmost-intro          -- the first line in a topmost construct definition
  234.  topmost-intro-cont     -- topmost definition continuation lines
  235.  member-init-intro      -- first line in a member initialization list
  236.  member-init-cont       -- subsequent member initialization list lines
  237.  inher-intro            -- first line of a multiple inheritance list
  238.  inher-cont             -- subsequent multiple inheritance lines
  239.  block-open             -- statement block open brace
  240.  block-close            -- statement block close brace
  241.  brace-list-open        -- open brace of an enum or static array list
  242.  brace-list-close       -- close brace of an enum or static array list
  243.  brace-list-intro       -- first line in an enum or static array list
  244.  brace-list-entry       -- subsequent lines in an enum or static array list
  245.  statement              -- a C/C++/ObjC statement
  246.  statement-cont         -- a continuation of a C/C++/ObjC statement
  247.  statement-block-intro  -- the first line in a new statement block
  248.  statement-case-intro   -- the first line in a case `block'
  249.  statement-case-open    -- the first line in a case block starting with brace
  250.  substatement           -- the first line after an if/while/for/do/else
  251.  substatement-open      -- the brace that opens a substatement block
  252.  case-label             -- a case or default label
  253.  access-label           -- C++ private/protected/public access label
  254.  label                  -- any non-special C/C++/ObjC label
  255.  do-while-closure       -- the `while' that ends a do/while construct
  256.  else-clause            -- the `else' of an if/else construct
  257.  comment-intro          -- a line containing only a comment introduction
  258.  arglist-intro          -- the first line in an argument list
  259.  arglist-cont           -- subsequent argument list lines when no
  260.                            arguments follow on the same line as the
  261.                            the arglist opening paren
  262.  arglist-cont-nonempty  -- subsequent argument list lines when at
  263.                            least one argument follows on the same
  264.                            line as the arglist opening paren
  265.  arglist-close          -- the solo close paren of an argument list
  266.  stream-op              -- lines continuing a stream operator construct
  267.  inclass                -- the construct is nested inside a class definition
  268.  cpp-macro              -- the start of a cpp macro
  269.  friend                 -- a C++ friend declaration
  270.  objc-method-intro      -- the first line of an Objective-C method definition
  271.  objc-method-args-cont  -- lines continuing an Objective-C method definition
  272.  objc-method-call-cont  -- lines continuing an Objective-C method call
  273. ")
  274.  
  275. (defvar c-tab-always-indent t
  276.   "*Controls the operation of the TAB key.
  277. If t, hitting TAB always just indents the current line.  If nil,
  278. hitting TAB indents the current line if point is at the left margin or
  279. in the line's indentation, otherwise it insert a real tab character.
  280. If other than nil or t, then tab is inserted only within literals
  281. -- defined as comments and strings -- and inside preprocessor
  282. directives, but line is always reindented.
  283.  
  284. Note that indentation of lines containing only comments is also
  285. controlled by the `c-comment-only-line-offset' variable.")
  286.  
  287. (defvar c-comment-only-line-offset 0
  288.   "*Extra offset for line which contains only the start of a comment.
  289. Can contain an integer or a cons cell of the form:
  290.  
  291.  (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
  292.  
  293. Where NON-ANCHORED-OFFSET is the amount of offset given to
  294. non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
  295. the amount of offset to give column-zero anchored comment-only lines.
  296. Just an integer as value is equivalent to (<val> . 0)")
  297.  
  298. (defvar c-block-comments-indent-p nil
  299.   "*Specifies how to re-indent C style block comments.
  300.  
  301. 4 styles of C block comments are supported.  If this variable is nil,
  302. then styles 1-3 are supported.  If this variable is non-nil, style 4
  303. only is supported.  Note that this currently has *no* effect on how
  304. comments are lined up or whether stars are inserted when C comments
  305. are auto-filled.  In any case, you still have to insert the stars
  306. manually.
  307.  
  308.  style 1:       style 2:       style 3:       style 4:
  309.  /*             /*             /*             /*
  310.     blah         * blah        ** blah        blah
  311.     blah         * blah        ** blah        blah
  312.     */           */            */             */")
  313.  
  314. (defvar c-cleanup-list '(scope-operator)
  315.   "*List of various C/C++/ObjC constructs to \"clean up\".
  316. These clean ups only take place when the auto-newline feature is turned
  317. on, as evidenced by the `/a' or `/ah' appearing next to the mode name.
  318. Valid symbols are:
  319.  
  320.  brace-else-brace    -- cleans up `} else {' constructs by placing entire
  321.                         construct on a single line.  This clean up only
  322.                         takes place when there is nothing but white
  323.                         space between the braces and the `else'.  Clean
  324.             up occurs when the open-brace after the `else'
  325.             is typed.
  326.  empty-defun-braces  -- cleans up empty defun braces by placing the
  327.                         braces on the same line.  Clean up occurs when
  328.             the defun closing brace is typed.
  329.  defun-close-semi    -- cleans up the terminating semi-colon on defuns
  330.             by placing the semi-colon on the same line as
  331.             the closing brace.  Clean up occurs when the
  332.             semi-colon is typed.
  333.  list-close-comma    -- cleans up commas following braces in array
  334.                         and aggregate initializers.  Clean up occurs
  335.             when the comma is typed.
  336.  scope-operator      -- cleans up double colons which may designate
  337.             a C++ scope operator split across multiple
  338.             lines. Note that certain C++ constructs can
  339.             generate ambiguous situations.  This clean up
  340.             only takes place when there is nothing but
  341.             whitespace between colons. Clean up occurs
  342.             when the second colon is typed.")
  343.  
  344. (defvar c-hanging-braces-alist '((brace-list-open)
  345.                  (substatement-open after))
  346.   "*Controls the insertion of newlines before and after braces.
  347. This variable contains an association list with elements of the
  348. following form: (SYNTACTIC-SYMBOL . (NL-LIST)).
  349.  
  350. SYNTACTIC-SYMBOL can be any of: defun-open, defun-close, class-open,
  351. class-close, inline-open, inline-close, block-open, block-close,
  352. substatement-open, statement-case-open, brace-list-open,
  353. brace-list-close, brace-list-intro, or brace-list-entry. See
  354. `c-offsets-alist' for details.
  355.  
  356. NL-LIST can contain any combination of the symbols `before' or
  357. `after'. It also be nil.  When a brace is inserted, the syntactic
  358. context it defines is looked up in this list, and if found, the
  359. NL-LIST is used to determine where newlines are inserted.  If not
  360. found, the default is to insert a newline both before and after
  361. braces.")
  362.  
  363. (defvar c-hanging-colons-alist nil
  364.   "*Controls the insertion of newlines before and after certain colons.
  365. This variable contains an association list with elements of the
  366. following form: (SYNTACTIC-SYMBOL . (NL-LIST)).
  367.  
  368. SYNTACTIC-SYMBOL can be any of: member-init-intro, inher-intro,
  369. case-label, label, and access-label. See `c-offsets-alist' for
  370. details.
  371.  
  372. NL-LIST can contain any combination of the symbols `before' or
  373. `after'. It also be nil.  When a colon is inserted, the language
  374. element that it defines is looked up in this list, and if found, the
  375. NL-LIST is used to determine where newlines are inserted.  If the
  376. language element for the colon is not found in this list, the default
  377. behavior is to not insert any newlines.")
  378.  
  379. (defvar c-hanging-comment-ender-p t
  380.   "*If nil, `c-fill-paragraph' leaves C block comment enders on their own line.
  381. Default value is t, which inhibits leaving block comment ending string
  382. `*/' on a line by itself.  This is BOCM's sole behavior.")
  383.  
  384. (defvar c-backslash-column 48
  385.   "*Column to insert backslashes when macroizing a region.")
  386. (defvar c-special-indent-hook nil
  387.   "*Hook for user defined special indentation adjustments.
  388. This hook gets called after a line is indented by the mode.")
  389. (defvar c-delete-function 'backward-delete-char-untabify
  390.   "*Function called by `c-electric-delete' when deleting a single char.")
  391. (defvar c-electric-pound-behavior nil
  392.   "*List of behaviors for electric pound insertion.
  393. Only currently supported behavior is `alignleft'.")
  394.  
  395. (defvar c-recognize-knr-p t
  396.   "*If non-nil, `c-mode' and `objc-mode' will recognize K&R constructs.
  397. This variable is needed because of ambiguities in C syntax that make
  398. fast recognition of K&R constructs problematic, and slow.  If you are
  399. coding with ANSI prototypes, set this variable to nil to speed up
  400. recognition of certain constructs.
  401.  
  402. This variable is nil by default in `c++-mode', and t by default in
  403. `c-mode' and `objc-mode'.  This variable is buffer-local.")
  404.  
  405. (defvar c-progress-interval 5
  406.   "*Interval used to update progress status during long re-indentation.
  407. If a number, percentage complete gets updated after each interval of
  408. that many seconds.   Set to nil to inhibit updating.  This is only
  409. useful for Emacs 19.")
  410.  
  411. (defvar c-style-alist
  412.   '(("GNU"
  413.      (c-basic-offset . 2)
  414.      (c-comment-only-line-offset . 0)
  415.      (c-offsets-alist . ((statement-block-intro . +)
  416.              (knr-argdecl-intro . 5)
  417.              (substatement-open . +)
  418.              (label . -)
  419.              (statement-cont . +)
  420.              (arglist-intro . c-lineup-arglist-intro-after-paren)
  421.              (arglist-close . c-lineup-arglist)
  422.              ))
  423.      )
  424.     ("K&R"
  425.      (c-basic-offset . 5)
  426.      (c-comment-only-line-offset . 0)
  427.      (c-offsets-alist . ((statement-block-intro . +)
  428.              (knr-argdecl-intro . 0)
  429.              (substatement-open . 0)
  430.              (label . -)
  431.              (statement-cont . +)
  432.              ))
  433.      )
  434.     ("BSD"
  435.      (c-basic-offset . 4)
  436.      (c-comment-only-line-offset . 0)
  437.      (c-offsets-alist . ((statement-block-intro . +)
  438.              (knr-argdecl-intro . +)
  439.              (substatement-open . 0)
  440.              (label . -)
  441.              (statement-cont . +)
  442.              ))
  443.      )
  444.     ("Stroustrup"
  445.      (c-basic-offset . 4)
  446.      (c-comment-only-line-offset . 0)
  447.      (c-offsets-alist . ((statement-block-intro . +)
  448.              (substatement-open . 0)
  449.              (label . -)
  450.              (statement-cont . +)
  451.              ))
  452.      )
  453.     ("Whitesmith"
  454.      (c-basic-offset . 4)
  455.      (c-comment-only-line-offset . 0)
  456.      (c-offsets-alist . ((statement-block-intro . +)
  457.              (knr-argdecl-intro . +)
  458.              (substatement-open . 0)
  459.              (label . -)
  460.              (statement-cont . +)
  461.              ))
  462.  
  463.      )
  464.     ("Ellemtel"
  465.      (c-basic-offset . 3)
  466.      (c-comment-only-line-offset . 0)
  467.      (c-hanging-braces-alist     . ((substatement-open before after)))
  468.      (c-offsets-alist . ((topmost-intro        . 0)
  469.                          (topmost-intro-cont   . 0)
  470.                          (substatement         . 3)
  471.              (substatement-open    . 0)
  472.              (statement-case-intro . 0)
  473.                          (case-label           . +)
  474.                          (access-label         . -3)
  475.                          (inclass              . 6)
  476.                          (inline-open          . 0)
  477.                          ))
  478.      ))
  479.   "Styles of Indentation.
  480. Elements of this alist are of the form:
  481.  
  482.   (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
  483.  
  484. where STYLE-STRING is a short descriptive string used to select a
  485. style, VARIABLE is any cc-mode variable, and VALUE is the intended
  486. value for that variable when using the selected style.
  487.  
  488. There is one special case when VARIABLE is `c-offsets-alist'.  In this
  489. case, the VALUE is a list containing elements of the form:
  490.  
  491.   (SYNTACTIC-SYMBOL . VALUE)
  492.  
  493. as described in `c-offsets-alist'.  These are passed directly to
  494. `c-set-offset' so there is no need to set every syntactic symbol in
  495. your style, only those that are different from the default.")
  496.  
  497. ;; dynamically append the default value of most variables
  498. (or (assoc "Default" c-style-alist)
  499.     (let* ((varlist '(c-inhibit-startup-warnings-p
  500.               c-strict-syntax-p
  501.               c-echo-syntactic-information-p
  502.               c-basic-offset
  503.               c-offsets-alist
  504.               c-tab-always-indent
  505.               c-comment-only-line-offset
  506.               c-block-comments-indent-p
  507.               c-cleanup-list
  508.               c-hanging-braces-alist
  509.               c-hanging-colons-alist
  510.               c-backslash-column
  511.               c-electric-pound-behavior))
  512.        (default (cons "Default"
  513.               (mapcar
  514.                (function
  515.                 (lambda (var)
  516.                   (cons var (symbol-value var))
  517.                   ))
  518.                varlist))))
  519.       (setq c-style-alist (cons default c-style-alist))))
  520.  
  521. (defvar c-mode-hook nil
  522.   "*Hook called by `c-mode'.")
  523. (defvar c++-mode-hook nil
  524.   "*Hook called by `c++-mode'.")
  525. (defvar objc-mode-hook nil
  526.   "*Hook called by `objc-mode'.")
  527.  
  528. (defvar c-mode-common-hook nil
  529.   "*Hook called by `c-mode', `c++-mode', and 'objc-mode' during common init.")
  530.  
  531. (defvar c-mode-menu
  532.   '(["Comment Out Region"     comment-region (mark)]
  533.     ["Macro Expand Region"    c-macro-expand (mark)]
  534.     ["Backslashify"           c-backslash-region (mark)]
  535.     ["Indent Expression"      c-indent-exp
  536.      (memq (following-char) '(?\( ?\[ ?\{))]
  537.     ["Indent Line"            c-indent-command t]
  538.     ["Fill Comment Paragraph" c-fill-paragraph t]
  539.     ["Up Conditional"         c-up-conditional t]
  540.     ["Backward Conditional"   c-backward-conditional t]
  541.     ["Forward Conditional"    c-forward-conditional t]
  542.     ["Backward Statement"     c-beginning-of-statement t]
  543.     ["Forward Statement"      c-end-of-statement t]
  544.     )
  545.   "XEmacs 19 (formerly Lucid) menu for C/C++/ObjC modes.")
  546.  
  547.  
  548. ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  549. ;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
  550.  
  551. (defconst c-emacs-features
  552.   (let ((major (and (boundp 'emacs-major-version)
  553.             emacs-major-version))
  554.     (minor (and (boundp 'emacs-minor-version)
  555.             emacs-minor-version))
  556.     flavor comments)
  557.     ;; figure out version numbers if not already discovered
  558.     (and (or (not major) (not minor))
  559.      (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
  560.      (setq major (string-to-int (substring emacs-version
  561.                            (match-beginning 1)
  562.                            (match-end 1)))
  563.            minor (string-to-int (substring emacs-version
  564.                            (match-beginning 2)
  565.                            (match-end 2)))))
  566.     (if (not (and major minor))
  567.     (error "Cannot figure out the major and minor version numbers."))
  568.     ;; calculate the major version
  569.     (cond
  570.      ((= major 18) (setq major 'v18))    ;Emacs 18
  571.      ((= major 4)  (setq major 'v18))    ;Epoch 4
  572.      ((= major 19) (setq major 'v19    ;Emacs 19
  573.              flavor (if (or (string-match "Lucid" emacs-version)
  574.                     (string-match "XEmacs" emacs-version))
  575.                     'XEmacs 'FSF)))
  576.      ;; I don't know
  577.      (t (error "Cannot recognize major version number: %s" major)))
  578.     ;; All XEmacs 19's (formerly Lucid) use 8-bit modify-syntax-entry
  579.     ;; flags, as do all patched (obsolete) FSF Emacs 19, Emacs 18,
  580.     ;; Epoch 4's.  Only vanilla FSF Emacs 19 uses 1-bit flag.  Lets be
  581.     ;; as smart as we can about figuring this out.
  582.     (if (eq major 'v19)
  583.     (let ((table (copy-syntax-table)))
  584.       (modify-syntax-entry ?a ". 12345678" table)
  585.       (if (= (logand (lsh (aref table ?a) -16) 255) 255)
  586.           (setq comments '8-bit)
  587.         (setq comments '1-bit)))
  588.       (setq comments 'no-dual-comments))
  589.     ;; lets do some minimal sanity checking.
  590.     (if (and (or
  591.           ;; Lemacs before 19.6 had bugs
  592.           (and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6))
  593.           ;; FSF 19 before 19.21 has known bugs
  594.           (and (eq major 'v19) (eq flavor 'FSF) (< minor 21)))
  595.          (not c-inhibit-startup-warnings-p))
  596.     (with-output-to-temp-buffer "*cc-mode warnings*"
  597.       (print (format
  598. "The version of Emacs that you are running, %s,
  599. has known bugs in its syntax.c parsing routines which will affect the
  600. performance of cc-mode. You should strongly consider upgrading to the
  601. latest available version.  cc-mode may continue to work, after a
  602. fashion, but strange indentation errors could be encountered."
  603.              emacs-version))))
  604.     ;; Emacs 18, with no patch is not too good
  605.     (if (and (eq major 'v18) (eq comments 'no-dual-comments)
  606.          (not c-inhibit-startup-warnings-p))
  607.     (with-output-to-temp-buffer "*cc-mode warnings*"
  608.       (print (format
  609. "The version of Emacs 18 you are running, %s,
  610. has known deficiencies in its ability to handle dual C++ comments,
  611. i.e. C++ line style comments and C block style comments.  This will
  612. not be much of a problem for you if you are only editing C code, but
  613. if you are doing much C++ editing, you should strongly consider
  614. upgrading to one of the latest Emacs 19's.  In Emacs 18, you may also
  615. experience performance degradations. Emacs 19 has some new built-in
  616. routines which will speed things up for you.
  617.  
  618. Because of these inherent problems, cc-mode is no longer being
  619. actively maintained for Emacs 18, however, until you can upgrade to
  620. Emacs 19, you may want to look at cc-mode-18.el in the cc-mode
  621. distribution.  THIS FILE IS COMPLETELY UNSUPPORTED!  If you use it,
  622. you are on your own, although patch contributions will be folded into
  623. the main release."
  624.                 emacs-version))))
  625.     ;; Emacs 18 with the syntax patches are no longer supported
  626.     (if (and (eq major 'v18) (not (eq comments 'no-dual-comments))
  627.          (not c-inhibit-startup-warnings-p))
  628.     (with-output-to-temp-buffer "*cc-mode warnings*"
  629.       (print (format
  630. "You are running a syntax patched Emacs 18 variant.  While this should
  631. work for you, you may want to consider upgrading to one of the latest
  632. Emacs 19's (FSF or XEmacs -- formerly Lucid).  The syntax patches are
  633. no longer supported either for syntax.c or cc-mode."))))
  634.     (list major comments))
  635.   "A list of features extant in the Emacs you are using.
  636. There are many flavors of Emacs out there, each with different
  637. features supporting those needed by cc-mode.  Here's the current
  638. supported list, along with the values for this variable:
  639.  
  640.  Vanilla Emacs 18/Epoch 4:   (v18 no-dual-comments)
  641.  Emacs 18/Epoch 4 (patch2):  (v18 8-bit)
  642.  XEmacs (formerly Lucid) 19: (v19 8-bit)
  643.  FSF Emacs 19:               (v19 1-bit).")
  644.  
  645. (defvar c++-mode-abbrev-table nil
  646.   "Abbrev table in use in c++-mode buffers.")
  647. (define-abbrev-table 'c++-mode-abbrev-table ())
  648.  
  649. (defvar c-mode-abbrev-table nil
  650.   "Abbrev table in use in c-mode buffers.")
  651. (define-abbrev-table 'c-mode-abbrev-table ())
  652.  
  653. (defvar objc-mode-abbrev-table nil
  654.   "Abbrev table in use in objc-mode buffers.")
  655. (define-abbrev-table 'objc-mode-abbrev-table ())
  656.  
  657. (defun c-mode-fsf-menu (name map)
  658.   ;; Add FSF menu to a keymap.  FSF menus suck.  Don't add them for
  659.   ;; XEmacs. This feature test will fail on other than FSF's Emacs 19.
  660.   (condition-case nil
  661.       (progn
  662.     (define-key map [menu-bar] (make-sparse-keymap))
  663.     (define-key map [menu-bar c] (cons name (make-sparse-keymap name)))
  664.  
  665.     (define-key map [menu-bar c comment-region]
  666.       '("Comment Out Region" . comment-region))
  667.     (define-key map [menu-bar c c-macro-expand]
  668.       '("Macro Expand Region" . c-macro-expand))
  669.     (define-key map [menu-bar c c-backslash-region]
  670.       '("Backslashify" . c-backslash-region))
  671.     (define-key map [menu-bar c indent-exp]
  672.       '("Indent Expression" . c-indent-exp))
  673.     (define-key map [menu-bar c indent-line]
  674.       '("Indent Line" . c-indent-command))
  675.     (define-key map [menu-bar c fill]
  676.       '("Fill Comment Paragraph" . c-fill-paragraph))
  677.     (define-key map [menu-bar c up]
  678.       '("Up Conditional" . c-up-conditional))
  679.     (define-key map [menu-bar c backward]
  680.       '("Backward Conditional" . c-backward-conditional))
  681.     (define-key map [menu-bar c forward]
  682.       '("Forward Conditional" . c-forward-conditional))
  683.     (define-key map [menu-bar c backward-stmt]
  684.       '("Backward Statement" . c-beginning-of-statement))
  685.     (define-key map [menu-bar c forward-stmt]
  686.       '("Forward Statement" . c-end-of-statement))
  687.  
  688.     ;; RMS: mouse-3 should not select this menu.  mouse-3's global
  689.     ;; definition is useful in C mode and we should not interfere
  690.     ;; with that.  The menu is mainly for beginners, and for them,
  691.     ;; the menubar requires less memory than a special click.
  692.     t)
  693.     (error nil)))
  694.  
  695. (defvar c-mode-map ()
  696.   "Keymap used in c-mode buffers.")
  697. (if c-mode-map
  698.     ()
  699.   ;; TBD: should we even worry about naming this keymap. My vote: no,
  700.   ;; because FSF and XEmacs (formerly Lucid) do it differently.
  701.   (setq c-mode-map (make-sparse-keymap))
  702.   ;; put standard keybindings into MAP
  703.   ;; the following mappings correspond more or less directly to BOCM
  704.   (define-key c-mode-map "{"         'c-electric-brace)
  705.   (define-key c-mode-map "}"         'c-electric-brace)
  706.   (define-key c-mode-map ";"         'c-electric-semi&comma)
  707.   (define-key c-mode-map "#"         'c-electric-pound)
  708.   (define-key c-mode-map ":"         'c-electric-colon)
  709.   ;; Lemacs 19.9 defines these two, the second of which is commented out
  710.   ;; (define-key c-mode-map "\e{" 'c-insert-braces)
  711.   ;; Commented out electric square brackets because nobody likes them.
  712.   ;; (define-key c-mode-map "[" 'c-insert-brackets)
  713.   (define-key c-mode-map "\e\C-h"    'c-mark-function)
  714.   (define-key c-mode-map "\e\C-q"    'c-indent-exp)
  715.   (define-key c-mode-map "\ea"       'c-beginning-of-statement)
  716.   (define-key c-mode-map "\ee"       'c-end-of-statement)
  717.   ;; I'd rather use an adaptive fill program instead of this.
  718.   (define-key c-mode-map "\eq"       'c-fill-paragraph)
  719.   (define-key c-mode-map "\C-c\C-n"  'c-forward-conditional)
  720.   (define-key c-mode-map "\C-c\C-p"  'c-backward-conditional)
  721.   (define-key c-mode-map "\C-c\C-u"  'c-up-conditional)
  722.   (define-key c-mode-map "\t"        'c-indent-command)
  723.   (define-key c-mode-map "\177"      'c-electric-delete)
  724.   ;; these are new keybindings, with no counterpart to BOCM
  725.   (define-key c-mode-map ","         'c-electric-semi&comma)
  726.   (define-key c-mode-map "/"         'c-electric-slash)
  727.   (define-key c-mode-map "*"         'c-electric-star)
  728.   (define-key c-mode-map "\C-c\C-q"  'c-indent-defun)
  729.   (define-key c-mode-map "\C-c\C-\\" 'c-backslash-region)
  730.   ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
  731.   (define-key c-mode-map "\C-c\C-a"  'c-toggle-auto-state)
  732.   (define-key c-mode-map "\C-c\C-b"  'c-submit-bug-report)
  733.   (define-key c-mode-map "\C-c\C-c"  'comment-region)
  734.   (define-key c-mode-map "\C-c\C-d"  'c-toggle-hungry-state)
  735.   (define-key c-mode-map "\C-c\C-e"  'c-macro-expand)
  736.   (define-key c-mode-map "\C-c\C-o"  'c-set-offset)
  737.   (define-key c-mode-map "\C-c\C-s"  'c-show-syntactic-information)
  738.   (define-key c-mode-map "\C-c\C-t"  'c-toggle-auto-hungry-state)
  739.   (define-key c-mode-map "\C-c\C-v"  'c-version)
  740.   ;; FSF Emacs 19 defines menus in the mode map. This call will return
  741.   ;; t on FSF Emacs 19, otherwise no-op and return nil.
  742.   (if (and (not (c-mode-fsf-menu "C" c-mode-map))
  743.        ;; in XEmacs (formerly Lucid) 19, we want the menu to popup
  744.        ;; when the 3rd button is hit.  In 19.10 and beyond this is
  745.        ;; done automatically if we put the menu on mode-popup-menu
  746.        ;; variable, see c-common-init. RMS decided that this
  747.        ;; feature should not be included for FSF's Emacs.
  748.        (boundp 'current-menubar)
  749.        (not (boundp 'mode-popup-menu)))
  750.       (define-key c-mode-map 'button3 'c-popup-menu)))
  751.  
  752. (defvar c++-mode-map ()
  753.   "Keymap used in c++-mode buffers.")
  754. (if c++-mode-map
  755.     ()
  756.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  757.   (if (memq 'v19 c-emacs-features)
  758.       ;; XEmacs (formerly Lucid) and FSF Emacs 19 do this differently
  759.       (if (not (fboundp 'set-keymap-parent))
  760.       (setq c++-mode-map (cons 'keymap c-mode-map))
  761.     (setq c++-mode-map (make-sparse-keymap))
  762.     (set-keymap-parent c++-mode-map c-mode-map))
  763.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  764.     (setq c++-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  765.   ;; add bindings which are only useful for C++
  766.   (define-key c++-mode-map "\C-c:"  'c-scope-operator)
  767.   ;; FSF Emacs 19 defines menus in the mode map. This call will return
  768.   ;; t on FSF Emacs 19, otherwise no-op and return nil.
  769.   (c-mode-fsf-menu "C++" c++-mode-map))
  770.  
  771. (defvar objc-mode-map ()
  772.   "Keymap used in objc-mode buffers.")
  773. (if objc-mode-map
  774.     ()
  775.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  776.   (if (memq 'v19 c-emacs-features)
  777.       ;; XEmacs (formerly Lucid) and FSF Emacs 19 do this differently
  778.       (if (not (fboundp 'set-keymap-parent))
  779.       (setq objc-mode-map (cons 'keymap c-mode-map))
  780.     (setq objc-mode-map (make-sparse-keymap))
  781.     (set-keymap-parent objc-mode-map c-mode-map))
  782.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  783.     (setq objc-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  784.   ;; add bindings which are only useful for Objective-C
  785.   ;;
  786.   ;; no additional bindings
  787.   ;;
  788.   ;; FSF Emacs 19 defines menus in the mode map. This call will return
  789.   ;; t on FSF Emacs 19, otherwise no-op and return nil.
  790.   (c-mode-fsf-menu "ObjC" objc-mode-map))
  791.  
  792. (defun c-populate-syntax-table (table)
  793.   ;; Populate the syntax TABLE
  794.   ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
  795.   (modify-syntax-entry ?\\ "\\"    table)
  796.   (modify-syntax-entry ?+  "."     table)
  797.   (modify-syntax-entry ?-  "."     table)
  798.   (modify-syntax-entry ?=  "."     table)
  799.   (modify-syntax-entry ?%  "."     table)
  800.   (modify-syntax-entry ?<  "."     table)
  801.   (modify-syntax-entry ?>  "."     table)
  802.   (modify-syntax-entry ?&  "."     table)
  803.   (modify-syntax-entry ?|  "."     table)
  804.   (modify-syntax-entry ?\' "\""    table))
  805.  
  806. (defvar c-mode-syntax-table nil
  807.   "Syntax table used in c-mode buffers.")
  808. (if c-mode-syntax-table
  809.     ()
  810.   (setq c-mode-syntax-table (make-syntax-table))
  811.   (c-populate-syntax-table c-mode-syntax-table)
  812.   ;; add extra comment syntax
  813.   (modify-syntax-entry ?/  ". 14"  c-mode-syntax-table)
  814.   (modify-syntax-entry ?*  ". 23"  c-mode-syntax-table))
  815.  
  816. (defvar c++-mode-syntax-table nil
  817.   "Syntax table used in c++-mode buffers.")
  818. (if c++-mode-syntax-table
  819.     ()
  820.   (setq c++-mode-syntax-table (make-syntax-table))
  821.   (c-populate-syntax-table c++-mode-syntax-table)
  822.   ;; add extra comment syntax
  823.   (cond
  824.    ((memq '8-bit c-emacs-features)
  825.     ;; XEmacs (formerly Lucid) has the best implementation
  826.     (modify-syntax-entry ?/  ". 1456" c++-mode-syntax-table)
  827.     (modify-syntax-entry ?*  ". 23"   c++-mode-syntax-table)
  828.     (modify-syntax-entry ?\n "> b"    c++-mode-syntax-table)
  829.     ;; Give CR the same syntax as newline, for selective-display
  830.     (modify-syntax-entry ?\^m "> b"    c++-mode-syntax-table))
  831.    ((memq '1-bit c-emacs-features)
  832.     ;; FSF Emacs 19 does things differently, but we can work with it
  833.     (modify-syntax-entry ?/  ". 124b" c++-mode-syntax-table)
  834.     (modify-syntax-entry ?*  ". 23"   c++-mode-syntax-table)
  835.     (modify-syntax-entry ?\n "> b"    c++-mode-syntax-table)
  836.     ;; Give CR the same syntax as newline, for selective-display
  837.     (modify-syntax-entry ?\^m "> b"    c++-mode-syntax-table))
  838.    )
  839.   ;; TBD: does it make sense for colon to be symbol class in C++?
  840.   ;; I'm not so sure, since c-label-key is busted on lines like:
  841.   ;; Foo::bar( i );
  842.   ;; maybe c-label-key should be fixed instead of commenting this out,
  843.   ;; but it also bothers me that this only seems appropriate for C++
  844.   ;; and not C.
  845.   ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
  846.   )
  847.  
  848. (defvar objc-mode-syntax-table nil
  849.   "Syntax table used in objc-mode buffers.")
  850. (if objc-mode-syntax-table
  851.     ()
  852.   (setq objc-mode-syntax-table (make-syntax-table))
  853.   (c-populate-syntax-table objc-mode-syntax-table)
  854.   ;; add extra comment syntax
  855.   (cond
  856.    ((memq '8-bit c-emacs-features)
  857.     ;; XEmacs (formerly Lucid) has the best implementation
  858.     (modify-syntax-entry ?/  ". 1456" objc-mode-syntax-table)
  859.     (modify-syntax-entry ?*  ". 23"   objc-mode-syntax-table)
  860.     (modify-syntax-entry ?\n "> b"    objc-mode-syntax-table)
  861.     ;; Give CR the same syntax as newline, for selective-display
  862.     (modify-syntax-entry ?\^m "> b"   objc-mode-syntax-table))
  863.    ((memq '1-bit c-emacs-features)
  864.     ;; FSF Emacs 19 does things differently, but we can work with it
  865.     (modify-syntax-entry ?/  ". 124b" objc-mode-syntax-table)
  866.     (modify-syntax-entry ?*  ". 23"   objc-mode-syntax-table)
  867.     (modify-syntax-entry ?\n "> b"    objc-mode-syntax-table)
  868.     ;; Give CR the same syntax as newline, for selective-display
  869.     (modify-syntax-entry ?\^m "> b"   objc-mode-syntax-table))
  870.    )
  871.   ;; everyone gets these
  872.   (modify-syntax-entry ?@ "_" objc-mode-syntax-table)
  873.   )
  874.  
  875. (defvar c-hungry-delete-key nil
  876.   "Internal state of hungry delete key feature.")
  877. (defvar c-auto-newline nil
  878.   "Internal state of auto newline feature.")
  879. (defvar c-auto-hungry-string nil
  880.   "Internal auto-newline/hungry-delete designation string for mode line.")
  881. (defvar c-syntactic-context nil
  882.   "Variable containing syntactic analysis list during indentation.")
  883. (defvar c-comment-start-regexp nil
  884.   "Buffer local variable describing how comment are introduced.")
  885. (defvar c-conditional-key nil
  886.   "Buffer local language-specific conditional keyword regexp.")
  887. (defvar c-access-key nil
  888.   "Buffer local language-specific access key regexp.")
  889. (defvar c-class-key nil
  890.   "Buffer local language-specific class key regexp.")
  891.  
  892. (make-variable-buffer-local 'c-auto-newline)
  893. (make-variable-buffer-local 'c-hungry-delete-key)
  894. (make-variable-buffer-local 'c-auto-hungry-string)
  895. (make-variable-buffer-local 'c-comment-start-regexp)
  896. (make-variable-buffer-local 'c-conditional-key)
  897. (make-variable-buffer-local 'c-access-key)
  898. (make-variable-buffer-local 'c-class-key)
  899. (make-variable-buffer-local 'c-recognize-knr-p)
  900.  
  901. ;; cmacexp is lame because it uses no preprocessor symbols.
  902. ;; It isn't very extensible either -- hardcodes /lib/cpp.
  903. ;; [I add it here only because c-mode has it -- BAW]]
  904. (autoload 'c-macro-expand "cmacexp"
  905.   "Display the result of expanding all C macros occurring in the region.
  906. The expansion is entirely correct because it uses the C preprocessor."
  907.   t)
  908.  
  909.  
  910. ;; constant regular expressions for looking at various constructs
  911. (defconst c-symbol-key "\\(\\w\\|\\s_\\)+"
  912.   "Regexp describing a C/C++/ObjC symbol.
  913. We cannot use just `word' syntax class since `_' cannot be in word
  914. class.  Putting underscore in word class breaks forward word movement
  915. behavior that users are familiar with.")
  916. (defconst c-C++-class-key "\\(class\\|struct\\|union\\)"
  917.   "Regexp describing a C++ class declaration, including templates.")
  918. (defconst c-inher-key
  919.   (concat "\\(\\<static\\>\\s +\\)?"
  920.       c-C++-class-key "[ \t]+" c-symbol-key
  921.       "\\([ \t]*:[ \t]*\\)?\\s *[^;]")
  922.   "Regexp describing a class inheritance declaration.")
  923. (defconst c-protection-key
  924.   "\\<\\(public\\|protected\\|private\\)\\>"
  925.   "Regexp describing protection keywords.")
  926. (defconst c-baseclass-key
  927.   (concat
  928.    ":?[ \t]*\\(virtual[ \t]+\\)?\\("
  929.    c-protection-key "[ \t]+\\)" c-symbol-key)
  930.   "Regexp describing base classes in a derived class definition.")
  931. (defconst c-switch-label-key
  932.   "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):"
  933.   "Regexp describing a switch's case or default label")
  934. (defconst c-C++-access-key
  935.   (concat c-protection-key ":")
  936.   "Regexp describing C++ access specification keywords.")
  937. (defconst c-label-key
  938.   (concat c-symbol-key ":\\([^:]\\|$\\)")
  939.   "Regexp describing any label.")
  940. (defconst c-C-conditional-key
  941.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\)\\b[^_]"
  942.   "Regexp describing a conditional control.")
  943. (defconst c-C++-conditional-key
  944.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\|try\\|catch\\)\\b[^_]"
  945.   "Regexp describing a conditional control for C++.")
  946.  
  947. (defconst c-ObjC-method-key
  948.   (concat
  949.    "^\\s *[+-]\\s *"
  950.    "\\(([^)]*)\\)?"            ; return type
  951.    ;; \\s- in objc syntax table does not include \n
  952.    ;; since it is considered the end of //-comments.
  953.    "[ \t\n]*" c-symbol-key)
  954.   "Regexp describing an Objective-C method intro.")
  955. (defconst c-ObjC-access-key
  956.   (concat "@" c-protection-key)
  957.   "Regexp describing access specification keywords for Objective-C.")
  958. (defconst c-ObjC-class-key
  959.   (concat
  960.    "@\\(interface\\|implementation\\)\\s +"
  961.    c-symbol-key                ;name of the class
  962.    "\\(\\s *:\\s *" c-symbol-key "\\)?"    ;maybe followed by the superclass
  963.    "\\(\\s *<[^>]+>\\)?"        ;and maybe the adopted protocols list
  964.    )
  965.   "Regexp describing a class or protocol declaration for Objective-C.")
  966.  
  967.  
  968. ;; main entry points for the modes
  969. ;;;###autoload
  970. (defun c++-mode ()
  971.   "Major mode for editing C++ code.
  972. cc-mode Revision: 4.85
  973. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  974. c++-mode buffer.  This automatically sets up a mail buffer with
  975. version information already added.  You just need to add a description
  976. of the problem, including a reproducable test case and send the
  977. message.
  978.  
  979. Note that the details of configuring c++-mode have been moved to the
  980. accompanying texinfo manual (which is not yet completed -- volunteers
  981. are welcome).  Until then, please read the README file that came with
  982. the cc-mode distribution.
  983.  
  984. The hook variable `c++-mode-hook' is run with no args, if that
  985. variable is bound and has a non-nil value.  Also the common hook
  986. c-mode-common-hook is run first, by this defun, `c-mode', and `objc-mode'.
  987.  
  988. Key bindings:
  989. \\{c++-mode-map}"
  990.   (interactive)
  991.   (kill-all-local-variables)
  992.   (set-syntax-table c++-mode-syntax-table)
  993.   (setq major-mode 'c++-mode
  994.     mode-name "C++"
  995.     local-abbrev-table c++-mode-abbrev-table
  996.     ;; should be set before c-common-init call
  997.     c-recognize-knr-p nil)
  998.   (use-local-map c++-mode-map)
  999.   (c-common-init)
  1000.   (setq comment-start "// "
  1001.     comment-end ""
  1002.     c-conditional-key c-C++-conditional-key
  1003.     c-comment-start-regexp "//\\|/\\*"
  1004.     c-class-key c-C++-class-key
  1005.     c-access-key c-C++-access-key)
  1006.   (run-hooks 'c++-mode-hook))
  1007.  
  1008. ;;;###autoload
  1009. (defun c-mode ()
  1010.   "Major mode for editing K&R and ANSI C code.
  1011. cc-mode Revision: 4.85
  1012. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  1013. c-mode buffer.  This automatically sets up a mail buffer with version
  1014. information already added.  You just need to add a description of the
  1015. problem, including a reproducable test case and send the message.
  1016.  
  1017. Note that the details of configuring c++-mode have been moved to the
  1018. accompanying texinfo manual (which is not yet completed -- volunteers
  1019. are welcome).  Until then, please read the README file that came with
  1020. the cc-mode distribution.
  1021.  
  1022. The hook variable `c-mode-hook' is run with no args, if that value is
  1023. bound and has a non-nil value.  Also the common hook
  1024. c-mode-common-hook is run first, by this defun, `c++-mode', and `objc-mode'.
  1025.  
  1026. Key bindings:
  1027. \\{c-mode-map}"
  1028.   (interactive)
  1029.   (kill-all-local-variables)
  1030.   (set-syntax-table c-mode-syntax-table)
  1031.   (setq major-mode 'c-mode
  1032.     mode-name "C"
  1033.     local-abbrev-table c-mode-abbrev-table
  1034.     ;; should be set before c-common-init call
  1035.     c-recognize-knr-p t)
  1036.   (use-local-map c-mode-map)
  1037.   (c-common-init)
  1038.   (setq comment-start "/* "
  1039.     comment-end   " */"
  1040.     c-conditional-key c-C-conditional-key
  1041.     c-class-key c-C++-class-key
  1042.     c-comment-start-regexp "/\\*")
  1043.   (run-hooks 'c-mode-hook))
  1044.  
  1045. ;;;###autoload
  1046. (defun objc-mode ()
  1047.   "Major mode for editing Objective C code.
  1048. cc-mode Revision: 4.85
  1049. To submit a problem report, enter `\\[c-submit-bug-report]' from an
  1050. objc-mode buffer.  This automatically sets up a mail buffer with
  1051. version information already added.  You just need to add a description
  1052. of the problem, including a reproducable test case and send the
  1053. message.
  1054.  
  1055. Note that the details of configuring c++-mode have been moved to the
  1056. accompanying texinfo manual (which is not yet completed -- volunteers
  1057. are welcome).  Until then, please read the README file that came with
  1058. the cc-mode distribution.
  1059.  
  1060. The hook variable `objc-mode-hook' is run with no args, if that value
  1061. is bound and has a non-nil value.  Also the common hook
  1062. c-mode-common-hook is run first, by this defun, `c-mode', and `c++-mode'.
  1063.  
  1064. Key bindings:
  1065. \\{objc-mode-map}"
  1066.   (interactive)
  1067.   (kill-all-local-variables)
  1068.   (set-syntax-table objc-mode-syntax-table)
  1069.   (setq major-mode 'objc-mode
  1070.     mode-name "ObjC"
  1071.     local-abbrev-table objc-mode-abbrev-table
  1072.     ;; should be set before c-common-init call
  1073.     c-recognize-knr-p t)
  1074.   (use-local-map objc-mode-map)
  1075.   (c-common-init)
  1076.   (setq comment-start "// "
  1077.     comment-end   ""
  1078.     c-conditional-key c-C-conditional-key
  1079.     c-comment-start-regexp "//\\|/\\*"
  1080.      c-class-key c-ObjC-class-key
  1081.     c-access-key c-ObjC-access-key)
  1082.   (run-hooks 'objc-mode-hook))
  1083.  
  1084. (defun c-common-init ()
  1085.   ;; Common initializations for c++-mode and c-mode.
  1086.   ;; make local variables
  1087.   (make-local-variable 'paragraph-start)
  1088.   (make-local-variable 'paragraph-separate)
  1089.   (make-local-variable 'paragraph-ignore-fill-prefix)
  1090.   (make-local-variable 'require-final-newline)
  1091.   (make-local-variable 'parse-sexp-ignore-comments)
  1092.   (make-local-variable 'indent-line-function)
  1093.   (make-local-variable 'indent-region-function)
  1094.   (make-local-variable 'comment-start)
  1095.   (make-local-variable 'comment-end)
  1096.   (make-local-variable 'comment-column)
  1097.   (make-local-variable 'comment-start-skip)
  1098.   ;; now set their values
  1099.   (setq paragraph-start (concat "^$\\|" page-delimiter)
  1100.     paragraph-separate paragraph-start
  1101.     paragraph-ignore-fill-prefix t
  1102.     require-final-newline t
  1103.     parse-sexp-ignore-comments t
  1104.     indent-line-function 'c-indent-line
  1105.     indent-region-function 'c-indent-region
  1106.     comment-column 32
  1107.     comment-start-skip "/\\*+ *\\|// *")
  1108.   ;; setup the comment indent variable in a Emacs version portable way
  1109.   ;; ignore any byte compiler warnings you might get here
  1110.   (if (boundp 'comment-indent-function)
  1111.       (progn
  1112.        (make-local-variable 'comment-indent-function)
  1113.        (setq comment-indent-function 'c-comment-indent))
  1114.     (make-local-variable 'comment-indent-hook)
  1115.     (setq comment-indent-hook 'c-comment-indent))
  1116.   ;; put C menu into menubar and on popup menu for XEmacs (formerly
  1117.   ;; Lucid) 19. I think this happens automatically for FSF Emacs 19.
  1118.   (if (and (boundp 'current-menubar)
  1119.        current-menubar
  1120.        (not (assoc mode-name current-menubar)))
  1121.       (progn
  1122.     (set-buffer-menubar (copy-sequence current-menubar))
  1123.     (add-menu nil mode-name c-mode-menu)))
  1124.   (if (boundp 'mode-popup-menu)
  1125.       (setq mode-popup-menu
  1126.         (cons (concat mode-name " Mode Commands") c-mode-menu)))
  1127.   ;; put auto-hungry designators onto minor-mode-alist, but only once
  1128.   (or (assq 'c-auto-hungry-string minor-mode-alist)
  1129.       (setq minor-mode-alist
  1130.         (cons '(c-auto-hungry-string c-auto-hungry-string)
  1131.           minor-mode-alist)))
  1132.   (run-hooks 'c-mode-common-hook))
  1133.  
  1134.  
  1135. ;; macros must be defined before first use
  1136. (defmacro c-point (position)
  1137.   ;; Returns the value of point at certain commonly referenced POSITIONs.
  1138.   ;; POSITION can be one of the following symbols:
  1139.   ;; 
  1140.   ;; bol  -- beginning of line
  1141.   ;; eol  -- end of line
  1142.   ;; bod  -- beginning of defun
  1143.   ;; boi  -- back to indentation
  1144.   ;; ionl -- indentation of next line
  1145.   ;; iopl -- indentation of previous line
  1146.   ;; bonl -- beginning of next line
  1147.   ;; bopl -- beginning of previous line
  1148.   ;; 
  1149.   ;; This function does not modify point or mark.
  1150.   (or (and (eq 'quote (car-safe position))
  1151.        (null (cdr (cdr position))))
  1152.       (error "bad buffer position requested: %s" position))
  1153.   (setq position (nth 1 position))
  1154.   (` (let ((here (point)))
  1155.        (,@ (cond
  1156.         ((eq position 'bol)  '((beginning-of-line)))
  1157.         ((eq position 'eol)  '((end-of-line)))
  1158.         ((eq position 'bod)
  1159.          '((beginning-of-defun)
  1160.            ;; if defun-prompt-regexp is non-nil, b-o-d won't leave
  1161.            ;; us at the open brace.
  1162.            (and (boundp 'defun-prompt-regexp)
  1163.             defun-prompt-regexp
  1164.             (looking-at defun-prompt-regexp)
  1165.             (goto-char (match-end 0)))
  1166.            ))
  1167.         ((eq position 'boi)  '((back-to-indentation)))
  1168.         ((eq position 'bonl) '((forward-line 1)))
  1169.         ((eq position 'bopl) '((forward-line -1)))
  1170.         ((eq position 'iopl)
  1171.          '((forward-line -1)
  1172.            (back-to-indentation)))
  1173.         ((eq position 'ionl)
  1174.          '((forward-line 1)
  1175.            (back-to-indentation)))
  1176.         (t (error "unknown buffer position requested: %s" position))
  1177.         ))
  1178.        (prog1
  1179.        (point)
  1180.      (goto-char here))
  1181.        ;; workaround for an Emacs18 bug -- blech! Well, at least it
  1182.        ;; doesn't hurt for v19
  1183.        (,@ nil)
  1184.        )))
  1185.  
  1186. (defmacro c-auto-newline ()
  1187.   ;; if auto-newline feature is turned on, insert a newline character
  1188.   ;; and return t, otherwise return nil.
  1189.   (` (and c-auto-newline
  1190.       (not (c-in-literal))
  1191.       (not (newline)))))
  1192.  
  1193. (defmacro c-safe (&rest body)
  1194.   ;; safely execute BODY, return nil if an error occurred
  1195.   (` (condition-case nil
  1196.      (progn (,@ body))
  1197.        (error nil))))
  1198.  
  1199. (defun c-insert-special-chars (arg)
  1200.   ;; simply call self-insert-command in Emacs 19
  1201.   (self-insert-command (prefix-numeric-value arg)))
  1202.  
  1203.  
  1204. ;; This is used by indent-for-comment to decide how much to indent a
  1205. ;; comment in C code based on its context.
  1206. (defun c-comment-indent ()
  1207.   (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
  1208.       0                ;Existing comment at bol stays there.
  1209.     (let ((opoint (point))
  1210.       placeholder)
  1211.       (save-excursion
  1212.     (beginning-of-line)
  1213.     (cond
  1214.      ;; CASE 1: A comment following a solitary close-brace should
  1215.      ;; have only one space.
  1216.      ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
  1217.                   c-comment-start-regexp
  1218.                   "\\)"))
  1219.       (search-forward "}")
  1220.       (1+ (current-column)))
  1221.      ;; CASE 2: 2 spaces after #endif
  1222.      ((or (looking-at "^#[ \t]*endif[ \t]*")
  1223.           (looking-at "^#[ \t]*else[ \t]*"))
  1224.       7)
  1225.      ;; CASE 3: use comment-column if previous line is a
  1226.      ;; comment-only line indented to the left of comment-column
  1227.      ((save-excursion
  1228.         (beginning-of-line)
  1229.         (and (not (bobp))
  1230.          (forward-line -1))
  1231.         (skip-chars-forward " \t")
  1232.         (prog1
  1233.         (looking-at c-comment-start-regexp)
  1234.           (setq placeholder (point))))
  1235.       (goto-char placeholder)
  1236.       (if (< (current-column) comment-column)
  1237.           comment-column
  1238.         (current-column)))
  1239.      ;; CASE 4: If comment-column is 0, and nothing but space
  1240.      ;; before the comment, align it at 0 rather than 1.
  1241.      ((progn
  1242.         (goto-char opoint)
  1243.         (skip-chars-backward " \t")
  1244.         (and (= comment-column 0) (bolp)))
  1245.       0)
  1246.      ;; CASE 5: indent at comment column except leave at least one
  1247.      ;; space.
  1248.      (t (max (1+ (current-column))
  1249.          comment-column))
  1250.      )))))
  1251.  
  1252.  
  1253. ;; active regions, and auto-newline/hungry delete key
  1254. (defun c-keep-region-active ()
  1255.   ;; do whatever is necessary to keep the region active in Xemacs
  1256.   ;; (formerly Lucid). ignore byte-compiler warnings you might see
  1257.   (and (boundp 'zmacs-region-stays)
  1258.        (setq zmacs-region-stays t)))
  1259.  
  1260. (defun c-update-modeline ()
  1261.   ;; set the c-auto-hungry-string for the correct designation on the modeline
  1262.   (setq c-auto-hungry-string
  1263.     (if c-auto-newline
  1264.         (if c-hungry-delete-key "/ah" "/a")
  1265.       (if c-hungry-delete-key "/h" nil)))
  1266.   ;; updates the modeline for all Emacsen
  1267.   (if (memq 'v19 c-emacs-features)
  1268.       (force-mode-line-update)
  1269.     (set-buffer-modified-p (buffer-modified-p))))
  1270.  
  1271. (defun c-calculate-state (arg prevstate)
  1272.   ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
  1273.   ;; arg is nil or zero, toggle the state. If arg is negative, turn
  1274.   ;; the state off, and if arg is positive, turn the state on
  1275.   (if (or (not arg)
  1276.       (zerop (setq arg (prefix-numeric-value arg))))
  1277.       (not prevstate)
  1278.     (> arg 0)))
  1279.  
  1280. (defun c-toggle-auto-state (arg)
  1281.   "Toggle auto-newline feature.
  1282. Optional numeric ARG, if supplied turns on auto-newline when positive,
  1283. turns it off when negative, and just toggles it when zero.
  1284.  
  1285. When the auto-newline feature is enabled (as evidenced by the `/a' or
  1286. `/ah' on the modeline after the mode name) newlines are automatically
  1287. inserted after special characters such as brace, comma, semi-colon,
  1288. and colon."
  1289.   (interactive "P")
  1290.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1291.   (c-update-modeline)
  1292.   (c-keep-region-active))
  1293.  
  1294. (defun c-toggle-hungry-state (arg)
  1295.   "Toggle hungry-delete-key feature.
  1296. Optional numeric ARG, if supplied turns on hungry-delete when positive,
  1297. turns it off when negative, and just toggles it when zero.
  1298.  
  1299. When the hungry-delete-key feature is enabled (as evidenced by the
  1300. `/h' or `/ah' on the modeline after the mode name) the delete key
  1301. gobbles all preceding whitespace in one fell swoop."
  1302.   (interactive "P")
  1303.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1304.   (c-update-modeline)
  1305.   (c-keep-region-active))
  1306.  
  1307. (defun c-toggle-auto-hungry-state (arg)
  1308.   "Toggle auto-newline and hungry-delete-key features.
  1309. Optional numeric ARG, if supplied turns on auto-newline and
  1310. hungry-delete when positive, turns them off when negative, and just
  1311. toggles them when zero.
  1312.  
  1313. See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
  1314.   (interactive "P")
  1315.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1316.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1317.   (c-update-modeline)
  1318.   (c-keep-region-active))
  1319.  
  1320.  
  1321. ;; COMMANDS
  1322. (defun c-electric-delete (arg)
  1323.   "Deletes preceding character or whitespace.
  1324. If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
  1325. \"/ah\" string on the mode line, then all preceding whitespace is
  1326. consumed.  If however an ARG is supplied, or `c-hungry-delete-key' is
  1327. nil, or point is inside a literal then the function in the variable
  1328. `c-delete-function' is called."
  1329.   (interactive "P")
  1330.   (if (or (not c-hungry-delete-key)
  1331.       arg
  1332.       (c-in-literal))
  1333.       (funcall c-delete-function (prefix-numeric-value arg))
  1334.     (let ((here (point)))
  1335.       (skip-chars-backward " \t\n")
  1336.       (if (/= (point) here)
  1337.       (delete-region (point) here)
  1338.     (funcall c-delete-function 1)
  1339.     ))))
  1340.  
  1341. (defun c-electric-pound (arg)
  1342.   "Electric pound (`#') insertion.
  1343. Inserts a `#' character specially depending on the variable
  1344. `c-electric-pound-behavior'.  If a numeric ARG is supplied, or if
  1345. point is inside a literal, nothing special happens."
  1346.   (interactive "P")
  1347.   (if (or (c-in-literal)
  1348.       arg
  1349.       (not (memq 'alignleft c-electric-pound-behavior)))
  1350.       ;; do nothing special
  1351.       (self-insert-command (prefix-numeric-value arg))
  1352.     ;; place the pound character at the left edge
  1353.     (let ((pos (- (point-max) (point)))
  1354.       (bolp (bolp)))
  1355.       (beginning-of-line)
  1356.       (delete-horizontal-space)
  1357.       (insert-char last-command-char 1)
  1358.       (and (not bolp)
  1359.        (goto-char (- (point-max) pos)))
  1360.       )))
  1361.  
  1362. (defun c-electric-brace (arg)
  1363.   "Insert a brace.
  1364.  
  1365. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  1366. or \"/ah\" string on the mode line, newlines are inserted before and
  1367. after braces based on the value of `c-hanging-braces-alist'.
  1368.  
  1369. Also, the line is re-indented unless a numeric ARG is supplied, there
  1370. are non-whitespace characters present on the line after the brace, or
  1371. the brace is inserted inside a literal."
  1372.   (interactive "P")
  1373.   (let* ((bod (c-point 'bod))
  1374.      (literal (c-in-literal bod))
  1375.      ;; we want to inhibit blinking the paren since this will be
  1376.      ;; most disruptive. we'll blink it ourselves later on
  1377.      (old-blink-paren (if (boundp 'blink-paren-function)
  1378.                   blink-paren-function
  1379.                 blink-paren-hook))
  1380.      blink-paren-function        ; emacs19
  1381.      blink-paren-hook        ; emacs18
  1382.      syntax newlines
  1383.      delete-temp-newline
  1384.      ;; shut this up
  1385.      (c-echo-syntactic-information-p nil))
  1386.     (if (or literal
  1387.         arg
  1388.         (not (looking-at "[ \t]*$")))
  1389.     (c-insert-special-chars arg)
  1390.       (setq syntax (progn
  1391.              ;; only insert a newline if there is
  1392.              ;; non-whitespace behind us
  1393.              (if (save-excursion
  1394.                (skip-chars-backward " \t")
  1395.                (not (bolp)))
  1396.              (progn (newline)
  1397.                 (setq delete-temp-newline t)))
  1398.              (self-insert-command (prefix-numeric-value arg))
  1399.              (c-guess-basic-syntax))
  1400.         newlines (and
  1401.               c-auto-newline
  1402.               (or (assq (car (or (assq 'defun-open syntax)
  1403.                      (assq 'defun-close syntax)
  1404.                      (assq 'class-open syntax)
  1405.                      (assq 'class-close syntax)
  1406.                      (assq 'inline-open syntax)
  1407.                      (assq 'inline-close syntax)
  1408.                      (assq 'brace-list-open syntax)
  1409.                      (assq 'brace-list-close syntax)
  1410.                      (assq 'brace-list-intro syntax)
  1411.                      (assq 'brace-list-entry syntax)
  1412.                      (assq 'block-open syntax)
  1413.                      (assq 'block-close syntax)
  1414.                      (assq 'substatement-open syntax)
  1415.                      (assq 'statement-case-open syntax)
  1416.                      ))
  1417.                 c-hanging-braces-alist)
  1418.               '(ignore before after))))
  1419.       ;; does a newline go before the open brace?
  1420.       (if (memq 'before newlines)
  1421.       ;; we leave the newline we've put in there before,
  1422.       ;; but we need to re-indent the line above
  1423.       (let ((pos (- (point-max) (point)))
  1424.         (here (point)))
  1425.         (forward-line -1)
  1426.         (c-indent-line)
  1427.         (goto-char (- (point-max) pos))
  1428.         ;; if the buffer has changed due to the indentation, we
  1429.         ;; need to recalculate syntax for the current line
  1430.         (if (/= (point) here)
  1431.         (setq syntax (c-guess-basic-syntax))))
  1432.     ;; must remove the newline we just stuck in (if we really did it)
  1433.     (and delete-temp-newline
  1434.          (delete-region (- (point) 2) (1- (point))))
  1435.     ;; since we're hanging the brace, we need to recalculate
  1436.     ;; syntax
  1437.     (setq syntax (c-guess-basic-syntax)))
  1438.       ;; now adjust the line's indentation
  1439.       (c-indent-line syntax)
  1440.       ;; Do all appropriate clean ups
  1441.       (let ((here (point))
  1442.         (pos (- (point-max) (point)))
  1443.         mbeg mend)
  1444.     ;; clean up empty defun braces
  1445.     (if (and c-auto-newline
  1446.          (memq 'empty-defun-braces c-cleanup-list)
  1447.          (= last-command-char ?\})
  1448.          (or (assq 'defun-close syntax)
  1449.              (assq 'class-close syntax)
  1450.              (assq 'inline-close syntax))
  1451.          (progn
  1452.            (forward-char -1)
  1453.            (skip-chars-backward " \t\n")
  1454.            (= (preceding-char) ?\{))
  1455.          ;; make sure matching open brace isn't in a comment
  1456.          (not (c-in-literal)))
  1457.         (delete-region (point) (1- here)))
  1458.     ;; clean up brace-else-brace
  1459.     (if (and c-auto-newline
  1460.          (memq 'brace-else-brace c-cleanup-list)
  1461.          (= last-command-char ?\{)
  1462.          (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
  1463.          (progn
  1464.            (setq mbeg (match-beginning 0)
  1465.              mend (match-end 0))
  1466.            (= mend here))
  1467.          (not (c-in-literal)))
  1468.         (progn
  1469.           (delete-region mbeg mend)
  1470.           (insert "} else {")))
  1471.     (goto-char (- (point-max) pos))
  1472.     )
  1473.       ;; does a newline go after the brace?
  1474.       (if (memq 'after (cdr-safe newlines))
  1475.       (progn
  1476.         (newline)
  1477.         (c-indent-line)))
  1478.       ;; blink the paren
  1479.       (and (= last-command-char ?\})
  1480.        old-blink-paren
  1481.        (save-excursion
  1482.          (c-backward-syntactic-ws bod)
  1483.          (if (boundp 'blink-paren-function)
  1484.          (funcall old-blink-paren)
  1485.            (run-hooks old-blink-paren))))
  1486.       )))
  1487.       
  1488. (defun c-electric-slash (arg)
  1489.   "Insert a slash character.
  1490. If slash is second of a double-slash C++ style comment introducing
  1491. construct, and we are on a comment-only-line, indent line as comment.
  1492. If numeric ARG is supplied or point is inside a literal, indentation
  1493. is inhibited."
  1494.   (interactive "P")
  1495.   (let ((indentp (and (memq major-mode '(c++-mode objc-mode))
  1496.               (not arg)
  1497.               (= (preceding-char) ?/)
  1498.               (= last-command-char ?/)
  1499.               (not (c-in-literal))))
  1500.     ;; shut this up
  1501.     (c-echo-syntactic-information-p nil))
  1502.     (self-insert-command (prefix-numeric-value arg))
  1503.     (if indentp
  1504.     (c-indent-line))))
  1505.  
  1506. (defun c-electric-star (arg)
  1507.   "Insert a star character.
  1508. If the star is the second character of a C style comment introducing
  1509. construct, and we are on a comment-only-line, indent line as comment.
  1510. If numeric ARG is supplied or point is inside a literal, indentation
  1511. is inhibited."
  1512.   (interactive "P")
  1513.   (self-insert-command (prefix-numeric-value arg))
  1514.   ;; if we are in a literal, or if arg is given do not re-indent the
  1515.   ;; current line, unless this star introduces a comment-only line.
  1516.   (if (and (not arg)
  1517.        (memq (c-in-literal) '(c))
  1518.        (= (preceding-char) ?*)
  1519.        (save-excursion
  1520.          (forward-char -1)
  1521.          (skip-chars-backward "*")
  1522.          (if (= (preceding-char) ?/)
  1523.          (forward-char -1))
  1524.          (skip-chars-backward " \t")
  1525.          (bolp)))
  1526.       ;; shut this up
  1527.       (let (c-echo-syntactic-information-p)
  1528.     (c-indent-line))
  1529.     ))
  1530.  
  1531. (defun c-electric-semi&comma (arg)
  1532.   "Insert a comma or semicolon.
  1533. When the auto-newline feature is turned on, as evidenced by the \"/a\"
  1534. or \"/ah\" string on the mode line, a newline is inserted after
  1535. semicolons, but not commas.
  1536.  
  1537. When semicolon is inserted, the line is re-indented unless a numeric
  1538. arg is supplied, point is inside a literal, or there are
  1539. non-whitespace characters on the line following the semicolon."
  1540.   (interactive "P")
  1541.   (let* ((bod (c-point 'bod))
  1542.      (literal (c-in-literal bod))
  1543.      (here (point))
  1544.      ;; shut this up
  1545.      (c-echo-syntactic-information-p nil))
  1546.     (if (or literal
  1547.         arg
  1548.         (not (looking-at "[ \t]*$")))
  1549.     (c-insert-special-chars arg)
  1550.       ;; do some special stuff with the character
  1551.       (self-insert-command (prefix-numeric-value arg))
  1552.       ;; do all cleanups, reindentations, and newline insertions, but
  1553.       ;; only if c-auto-newline is turned on
  1554.       (if (not c-auto-newline) nil
  1555.     ;; clean ups
  1556.     (let ((pos (- (point-max) (point))))
  1557.       (if (and (or (and
  1558.             (= last-command-char ?,)
  1559.             (memq 'list-close-comma c-cleanup-list))
  1560.                (and
  1561.             (= last-command-char ?\;)
  1562.             (memq 'defun-close-semi c-cleanup-list)))
  1563.            (progn
  1564.              (forward-char -1)
  1565.              (skip-chars-backward " \t\n")
  1566.              (= (preceding-char) ?}))
  1567.            ;; make sure matching open brace isn't in a comment
  1568.            (not (c-in-literal)))
  1569.           (delete-region (point) here))
  1570.       (goto-char (- (point-max) pos)))
  1571.     ;; re-indent line
  1572.     (c-indent-line)
  1573.     ;; newline only after semicolon, but only if that semicolon is
  1574.     ;; not inside a parenthesis list (e.g. a for loop statement)
  1575.     (and (= last-command-char ?\;)
  1576.          (condition-case nil
  1577.          (save-excursion
  1578.            (up-list -1)
  1579.            (/= (following-char) ?\())
  1580.            (error t))
  1581.          (progn (newline) t)
  1582.          (c-indent-line))
  1583.     ))))
  1584.  
  1585. (defun c-electric-colon (arg)
  1586.   "Insert a colon.
  1587.  
  1588. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  1589. or \"/ah\" string on the mode line, newlines are inserted before and
  1590. after colons based on the value of `c-hanging-colons-alist'.
  1591.  
  1592. Also, the line is re-indented unless a numeric ARG is supplied, there
  1593. are non-whitespace characters present on the line after the colon, or
  1594. the colon is inserted inside a literal.
  1595.  
  1596. This function cleans up double colon scope operators based on the
  1597. value of `c-cleanup-list'."
  1598.   (interactive "P")
  1599.   (let* ((bod (c-point 'bod))
  1600.      (literal (c-in-literal bod))
  1601.      syntax newlines
  1602.      ;; shut this up
  1603.      (c-echo-syntactic-information-p nil))
  1604.     (if (or literal
  1605.         arg
  1606.         (not (looking-at "[ \t]*$")))
  1607.     (c-insert-special-chars arg)
  1608.       ;; insert the colon, then do any specified cleanups
  1609.       (self-insert-command (prefix-numeric-value arg))
  1610.       (let ((pos (- (point-max) (point)))
  1611.         (here (point)))
  1612.     (if (and c-auto-newline
  1613.          (memq 'scope-operator c-cleanup-list)
  1614.          (= (preceding-char) ?:)
  1615.          (progn
  1616.            (forward-char -1)
  1617.            (skip-chars-backward " \t\n")
  1618.            (= (preceding-char) ?:))
  1619.          (not (c-in-literal))
  1620.          (not (= (char-after (- (point) 2)) ?:)))
  1621.         (delete-region (point) (1- here)))
  1622.     (goto-char (- (point-max) pos)))
  1623.       ;; lets do some special stuff with the colon character
  1624.       (setq syntax (c-guess-basic-syntax)
  1625.         ;; some language elements can only be determined by
  1626.         ;; checking the following line.  Lets first look for ones
  1627.         ;; that can be found when looking on the line with the
  1628.         ;; colon
  1629.         newlines
  1630.         (and c-auto-newline
  1631.          (or
  1632.           (let ((langelem (or (assq 'case-label syntax)
  1633.                       (assq 'label syntax)
  1634.                       (assq 'access-label syntax))))
  1635.             (and langelem
  1636.              (assq (car langelem) c-hanging-colons-alist)))
  1637.           (prog2
  1638.               (insert "\n")
  1639.               (let* ((syntax (c-guess-basic-syntax))
  1640.                  (langelem
  1641.                   (or (assq 'member-init-intro syntax)
  1642.                   (assq 'inher-intro syntax))))
  1643.             (and langelem
  1644.                  (assq (car langelem) c-hanging-colons-alist)))
  1645.             (delete-char -1))
  1646.           )))
  1647.       ;; indent the current line
  1648.       (c-indent-line syntax)
  1649.       ;; does a newline go before the colon?
  1650.       (if (memq 'before newlines)
  1651.       (let ((pos (- (point-max) (point))))
  1652.         (forward-char -1)
  1653.         (newline)
  1654.         (c-indent-line)
  1655.         (goto-char (- (point-max) pos))))
  1656.       ;; does a newline go after the colon?
  1657.       (if (memq 'after (cdr-safe newlines))
  1658.       (progn
  1659.         (newline)
  1660.         (c-indent-line)))
  1661.       )))
  1662.  
  1663. (defun c-read-offset (langelem)
  1664.   ;; read new offset value for LANGELEM from minibuffer. return a
  1665.   ;; legal value only
  1666.   (let ((oldoff (format "%s" (cdr-safe (assq langelem c-offsets-alist))))
  1667.     (errmsg "Offset must be int, func, var, or one of +, -, ++, --: ")
  1668.     (prompt "Offset: ")
  1669.     offset input interned)
  1670.     (while (not offset)
  1671.       (setq input (read-string prompt oldoff)
  1672.         offset (cond ((string-equal "+" input) '+)
  1673.              ((string-equal "-" input) '-)
  1674.              ((string-equal "++" input) '++)
  1675.              ((string-equal "--" input) '--)
  1676.              ((string-match "^-?[0-9]+$" input)
  1677.               (string-to-int input))
  1678.              ((fboundp (setq interned (intern input)))
  1679.               interned)
  1680.              ((boundp interned) interned)
  1681.              ;; error, but don't signal one, keep trying
  1682.              ;; to read an input value
  1683.              (t (ding)
  1684.                 (setq prompt errmsg)
  1685.                 nil))))
  1686.     offset))
  1687.  
  1688. (defun c-set-offset (symbol offset &optional add-p)
  1689.   "Change the value of a syntactic element symbol in `c-offsets-alist'.
  1690. SYMBOL is the syntactic element symbol to change and OFFSET is the new
  1691. offset for that syntactic element.  Optional ADD says to add SYMBOL to
  1692. `c-offsets-alist' if it doesn't already appear there."
  1693.   (interactive
  1694.    (let* ((langelem
  1695.        (intern (completing-read
  1696.             (concat "Syntactic symbol to change"
  1697.                 (if current-prefix-arg " or add" "")
  1698.                 ": ")
  1699.             (mapcar
  1700.              (function
  1701.               (lambda (langelem)
  1702.             (cons (format "%s" (car langelem)) nil)))
  1703.              c-offsets-alist)
  1704.             nil (not current-prefix-arg)
  1705.             ;; initial contents tries to be the last element
  1706.             ;; on the syntactic analysis list for the current
  1707.             ;; line
  1708.             (let* ((syntax (c-guess-basic-syntax))
  1709.                (len (length syntax))
  1710.                (ic (format "%s" (car (nth (1- len) syntax)))))
  1711.               (if (memq 'v19 c-emacs-features)
  1712.               (cons ic 0)
  1713.             ic))
  1714.             )))
  1715.       (offset (c-read-offset langelem)))
  1716.      (list langelem offset current-prefix-arg)))
  1717.   ;; sanity check offset
  1718.   (or (eq offset '+)
  1719.       (eq offset '-)
  1720.       (eq offset '++)
  1721.       (eq offset '--)
  1722.       (integerp offset)
  1723.       (fboundp offset)
  1724.       (boundp offset)
  1725.       (error "Offset must be int, func, var, or one of +, -, ++, --: %s"
  1726.          offset))
  1727.   (let ((entry (assq symbol c-offsets-alist)))
  1728.     (if entry
  1729.     (setcdr entry offset)
  1730.       (if add-p
  1731.       (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
  1732.     (error "%s is not a valid syntactic symbol." symbol))))
  1733.   (c-keep-region-active))
  1734.  
  1735. (defun c-set-style (style &optional local)
  1736.   "Set cc-mode variables to use one of several different indentation styles.
  1737. STYLE is a string representing the desired style and optional LOCAL is
  1738. a flag which, if non-nil, means to make the style variables being
  1739. changed buffer local, instead of the default, which is to set the
  1740. global variables.  Interactively, the flag comes from the prefix
  1741. argument.  The styles are chosen from the `c-style-alist' variable."
  1742.   (interactive (list (completing-read "Use which C indentation style? "
  1743.                                       c-style-alist nil t)
  1744.              current-prefix-arg))
  1745.   (let ((vars (cdr (assoc style c-style-alist))))
  1746.     (or vars
  1747.     (error "Invalid C indentation style `%s'" style))
  1748.     ;; set all the variables
  1749.     (mapcar
  1750.      (function
  1751.       (lambda (varentry)
  1752.     (let ((var (car varentry))
  1753.           (val (cdr varentry)))
  1754.       (and local
  1755.            (make-local-variable var))
  1756.       ;; special case for c-offsets-alist
  1757.       (if (not (eq var 'c-offsets-alist))
  1758.           (set var val)
  1759.         ;; reset c-offsets-alist to the default value first
  1760.         (setq c-offsets-alist (copy-alist c-offsets-alist-default))
  1761.         ;; now set the langelems that are different
  1762.         (mapcar
  1763.          (function
  1764.           (lambda (langentry)
  1765.         (let ((langelem (car langentry))
  1766.               (offset (cdr langentry)))
  1767.           (c-set-offset langelem offset)
  1768.           )))
  1769.          val))
  1770.       )))
  1771.      vars))
  1772.   (c-keep-region-active))
  1773.  
  1774. (defun c-fill-paragraph (&optional arg)
  1775.   "Like \\[fill-paragraph] but handles C and C++ style comments.
  1776. If any of the current line is a comment or within a comment,
  1777. fill the comment or the paragraph of it that point is in,
  1778. preserving the comment indentation or line-starting decorations."
  1779.   (interactive "P")
  1780.   (let* (comment-start-place
  1781.      (first-line
  1782.       ;; Check for obvious entry to comment.
  1783.       (save-excursion
  1784.         (beginning-of-line)
  1785.         (skip-chars-forward " \t\n")
  1786.         (and (looking-at comment-start-skip)
  1787.          (setq comment-start-place (point))))))
  1788.     (if (and (memq major-mode '(c++-mode objc-mode))
  1789.          (save-excursion
  1790.            (beginning-of-line)
  1791.            (looking-at ".*//")))
  1792.     (let (fill-prefix
  1793.           (paragraph-start
  1794.            ;; Lines containing just a comment start or just an end
  1795.            ;; should not be filled into paragraphs they are next to.
  1796.            (concat 
  1797.         paragraph-start
  1798.         "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  1799.           (paragraph-separate
  1800.            (concat
  1801.         paragraph-separate
  1802.         "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$")))
  1803.       (save-excursion
  1804.         (beginning-of-line)
  1805.         ;; Move up to first line of this comment.
  1806.         (while (and (not (bobp))
  1807.             (looking-at "[ \t]*//"))
  1808.           (forward-line -1))
  1809.         (if (not (looking-at ".*//"))
  1810.         (forward-line 1))
  1811.         ;; Find the comment start in this line.
  1812.         (re-search-forward "[ \t]*//[ \t]*")
  1813.         ;; Set the fill-prefix to be what all lines except the first
  1814.         ;; should start with.
  1815.         (setq fill-prefix (buffer-substring (match-beginning 0)
  1816.                         (match-end 0)))
  1817.         (save-restriction
  1818.           ;; Narrow down to just the lines of this comment.
  1819.           (narrow-to-region (c-point 'bol)
  1820.                 (save-excursion
  1821.                   (forward-line 1)
  1822.                   (while (looking-at fill-prefix)
  1823.                     (forward-line 1))
  1824.                   (point)))
  1825.           (fill-paragraph arg)
  1826.           )))
  1827.       ;; else C style comments
  1828.       (if (or first-line
  1829.           ;; t if we enter a comment between start of function and
  1830.           ;; this line.
  1831.           (eq (c-in-literal) 'c)
  1832.           ;; t if this line contains a comment starter.
  1833.           (setq first-line
  1834.             (save-excursion
  1835.               (beginning-of-line)
  1836.               (prog1
  1837.               (re-search-forward comment-start-skip
  1838.                          (save-excursion (end-of-line)
  1839.                                  (point))
  1840.                          t)
  1841.             (setq comment-start-place (point))))))
  1842.       ;; Inside a comment: fill one comment paragraph.
  1843.       (let ((fill-prefix
  1844.          ;; The prefix for each line of this paragraph
  1845.          ;; is the appropriate part of the start of this line,
  1846.          ;; up to the column at which text should be indented.
  1847.          (save-excursion
  1848.            (beginning-of-line)
  1849.            (if (looking-at "[ \t]*/\\*.*\\*/")
  1850.                (progn (re-search-forward comment-start-skip)
  1851.                   (make-string (current-column) ?\ ))
  1852.              (if first-line (forward-line 1))
  1853.  
  1854.              (let ((line-width (progn (end-of-line) (current-column))))
  1855.                (beginning-of-line)
  1856.                (prog1
  1857.                (buffer-substring
  1858.                 (point)
  1859.  
  1860.                 ;; How shall we decide where the end of the
  1861.                 ;; fill-prefix is?
  1862.                 (progn
  1863.                   (beginning-of-line)
  1864.                   (skip-chars-forward " \t*" (c-point 'eol))
  1865.                   (point)))
  1866.  
  1867.              ;; If the comment is only one line followed
  1868.              ;; by a blank line, calling move-to-column
  1869.              ;; above may have added some spaces and tabs
  1870.              ;; to the end of the line; the fill-paragraph
  1871.              ;; function will then delete it and the
  1872.              ;; newline following it, so we'll lose a
  1873.              ;; blank line when we shouldn't.  So delete
  1874.              ;; anything move-to-column added to the end
  1875.              ;; of the line.  We record the line width
  1876.              ;; instead of the position of the old line
  1877.              ;; end because move-to-column might break a
  1878.              ;; tab into spaces, and the new characters
  1879.              ;; introduced there shouldn't be deleted.
  1880.  
  1881.              ;; If you can see a better way to do this,
  1882.              ;; please make the change.  This seems very
  1883.              ;; messy to me.
  1884.              (delete-region (progn (move-to-column line-width)
  1885.                            (point))
  1886.                     (progn (end-of-line) (point))))))))
  1887.  
  1888.         (paragraph-start
  1889.          ;; Lines containing just a comment start or just an end
  1890.          ;; should not be filled into paragraphs they are next to.
  1891.          (concat 
  1892.           paragraph-start
  1893.           "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  1894.         (paragraph-separate
  1895.          (concat
  1896.           paragraph-separate
  1897.           "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  1898.         (chars-to-delete 0))
  1899.         (save-restriction
  1900.           ;; Don't fill the comment together with the code
  1901.           ;; following it.  So temporarily exclude everything
  1902.           ;; before the comment start, and everything after the
  1903.           ;; line where the comment ends.  If comment-start-place
  1904.           ;; is non-nil, the comment starter is there.  Otherwise,
  1905.           ;; point is inside the comment.
  1906.           (narrow-to-region (save-excursion
  1907.                   (if comment-start-place
  1908.                       (goto-char comment-start-place)
  1909.                     (search-backward "/*"))
  1910.                   ;; Protect text before the comment
  1911.                   ;; start by excluding it.  Add
  1912.                   ;; spaces to bring back proper
  1913.                   ;; indentation of that point.
  1914.                   (let ((column (current-column)))
  1915.                     (prog1 (point)
  1916.                       (setq chars-to-delete column)
  1917.                       (insert-char ?\  column))))
  1918.                 (save-excursion
  1919.                   (if comment-start-place
  1920.                       (goto-char (+ comment-start-place 2)))
  1921.                   (search-forward "*/" nil 'move)
  1922.                   (forward-line 1)
  1923.                   (point)))
  1924.           (fill-paragraph arg)
  1925.           (save-excursion
  1926.         ;; Delete the chars we inserted to avoid clobbering
  1927.         ;; the stuff before the comment start.
  1928.         (goto-char (point-min))
  1929.         (if (> chars-to-delete 0)
  1930.             (delete-region (point) (+ (point) chars-to-delete)))
  1931.         ;; Find the comment ender (should be on last line of
  1932.         ;; buffer, given the narrowing) and don't leave it on
  1933.         ;; its own line, unless that's the style that's desired.
  1934.         (goto-char (point-max))
  1935.         (forward-line -1)
  1936.         (search-forward "*/" nil 'move)
  1937.         (beginning-of-line)
  1938.         (if (and c-hanging-comment-ender-p
  1939.              (looking-at "[ \t]*\\*/"))
  1940.             ;(delete-indentation)))))
  1941.             (let ((fill-column (+ fill-column 9999)))
  1942.               (forward-line -1)
  1943.               (fill-region-as-paragraph (point) (point-max)))))))
  1944.     ;; Outside of comments: do ordinary filling.
  1945.     (fill-paragraph arg)))))
  1946.  
  1947. ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
  1948. ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
  1949. (defun c-forward-into-nomenclature (&optional arg)
  1950.   "Move forward to end of a nomenclature section or word.
  1951. With arg, to it arg times."
  1952.   (interactive "p")
  1953.   (let ((case-fold-search nil))
  1954.     (if (> arg 0)
  1955.     (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
  1956.       (while (and (< arg 0)
  1957.           (re-search-backward
  1958.            "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
  1959.            (point-min) 0))
  1960.     (forward-char 1)
  1961.     (setq arg (1+ arg)))))
  1962.   (c-keep-region-active))
  1963.  
  1964. (defun c-backward-into-nomenclature (&optional arg)
  1965.   "Move backward to beginning of a nomenclature section or word.
  1966. With optional ARG, move that many times.  If ARG is negative, move
  1967. forward."
  1968.   (interactive "p")
  1969.   (c-forward-into-nomenclature (- arg))
  1970.   (c-keep-region-active))
  1971.  
  1972. (defun c-scope-operator ()
  1973.   "Insert a double colon scope operator at point.
  1974. No indentation or other \"electric\" behavior is performed."
  1975.   (interactive)
  1976.   (insert "::"))
  1977.  
  1978. ;; TBD: These are from XEmacs (formerly Lucid) 19.9's version of c-mode.el
  1979. ;;(defun c-insert-brackets ()
  1980. ;;  (interactive)
  1981. ;;  (insert ?[)
  1982. ;;  (save-excursion
  1983. ;;    (insert ?])))
  1984.  
  1985. ;;(defun c-insert-braces ()
  1986. ;;  (interactive)
  1987. ;;  (setq last-command-char ?{)
  1988. ;;  (electric-c-brace 1)
  1989. ;;  (newline)
  1990. ;;  (c-indent-line)
  1991. ;;  (save-excursion
  1992. ;;    (newline)
  1993. ;;    (insert ?})
  1994. ;;    (c-indent-line)))
  1995.  
  1996.  
  1997. (defun c-beginning-of-statement (&optional count lim)
  1998.   "Go to the beginning of the innermost C statement.
  1999. With prefix arg, go back N - 1 statements.  If already at the
  2000. beginning of a statement then go to the beginning of the preceding
  2001. one.  If within a string or comment, or next to a comment (only
  2002. whitespace between), move by sentences instead of statements.
  2003.  
  2004. When called from a program, this function takes 2 optional args: the
  2005. prefix arg, and a buffer position limit which is the farthest back to
  2006. search."
  2007.   (interactive "p")
  2008.   (let ((here (point))
  2009.     (count (or count 1))
  2010.     (lim (or lim (c-point 'bod)))
  2011.     state)
  2012.     (save-excursion
  2013.       (goto-char lim)
  2014.       (setq state (parse-partial-sexp (point) here nil nil)))
  2015.     (if (and (interactive-p)
  2016.          (or (nth 3 state)
  2017.          (nth 4 state)
  2018.          (looking-at (concat "[ \t]*" comment-start-skip))
  2019.          (save-excursion
  2020.            (skip-chars-backward " \t")
  2021.            (goto-char (- (point) 2))
  2022.            (looking-at "\\*/"))))
  2023.     (forward-sentence (- count))
  2024.       (while (> count 0)
  2025.     (c-beginning-of-statement-1)
  2026.     (setq count (1- count)))
  2027.       (while (< count 0)
  2028.     (c-end-of-statement-1)
  2029.     (setq count (1+ count))))
  2030.     ;; its possible we've been left up-buf of lim
  2031.     (goto-char (max (point) lim))
  2032.     )
  2033.   (c-keep-region-active))
  2034.  
  2035. (defun c-end-of-statement (&optional count lim)
  2036.   "Go to the end of the innermost C statement.
  2037.  
  2038. With prefix arg, go forward N - 1 statements.  Move forward to end of
  2039. the next statement if already at end.  If within a string or comment,
  2040. move by sentences instead of statements.
  2041.  
  2042. When called from a program, this function takes 2 optional args: the
  2043. prefix arg, and a buffer position limit which is the farthest back to
  2044. search."
  2045.   (interactive "p")
  2046.   (c-beginning-of-statement (- (or count 1)) lim)
  2047.   (c-keep-region-active))
  2048.  
  2049. (defun c-beginning-of-statement-1 ()
  2050.   ;; move to the start of the current statement, or the previous
  2051.   ;; statement if already at the beginning of one.
  2052.   (let ((firstp t)
  2053.     donep c-in-literal-cache maybe-labelp
  2054.     (last-begin (point)))
  2055.     (while (not donep)
  2056.       ;; stop at beginning of buffer
  2057.       (if (bobp) (setq donep t)
  2058.     ;; go backwards one balanced expression, but be careful of
  2059.     ;; unbalanced paren being reached
  2060.     (if (not (c-safe (progn (backward-sexp 1) t)))
  2061.         (progn
  2062.           (if firstp
  2063.           (backward-up-list 1)
  2064.         (goto-char last-begin))
  2065.           ;; skip over any unary operators, or other special
  2066.           ;; characters appearing at front of identifier
  2067.           (save-excursion
  2068.         (c-backward-syntactic-ws)
  2069.         (skip-chars-backward "-+!*&:.~ \t\n")
  2070.         (if (= (preceding-char) ?\()
  2071.             (setq last-begin (point))))
  2072.           (goto-char last-begin)
  2073.           (setq last-begin (point)
  2074.             donep t)))
  2075.  
  2076.     (setq maybe-labelp nil)
  2077.     ;; see if we're in a literal. if not, then this bufpos may be
  2078.     ;; a candidate for stopping
  2079.     (cond
  2080.      ;; CASE 0: did we hit the error condition above?
  2081.      (donep)
  2082.      ;; CASE 1: are we in a literal?
  2083.      ((eq (c-in-literal) 'pound)
  2084.       (beginning-of-line))
  2085.      ;; CASE 2: some other kind of literal?
  2086.      ((c-in-literal))
  2087.      ;; CASE 3: are we looking at a conditional keyword?
  2088.      ((or (looking-at c-conditional-key)
  2089.           (and (= (following-char) ?\()
  2090.            (let ((here (point))
  2091.              (foundp (progn
  2092.                    (c-backward-syntactic-ws)
  2093.                    (forward-word -1)
  2094.                    (looking-at c-conditional-key))))
  2095.              (if (not foundp)
  2096.              (goto-char here))
  2097.              foundp)))
  2098.       ;; are we in the middle of an else-if clause?
  2099.       (if (save-excursion
  2100.         (c-safe (forward-sexp -1))
  2101.         (looking-at "\\<else\\>[ \t]+\\<if\\>"))
  2102.           (forward-sexp -1))
  2103.       (setq last-begin (point)
  2104.         donep t))
  2105.      ;; CASE 4: is this the first time we're checking?
  2106.      (firstp (setq firstp nil
  2107.                last-begin (point)))
  2108.      ;; CASE 5: have we crossed a statement barrier?
  2109.      ((let ((lim (point))
  2110.         crossedp)
  2111.         (save-excursion
  2112.           (while (and (not crossedp)
  2113.               (< (point) last-begin))
  2114.         (skip-chars-forward "^;{}:" last-begin)
  2115.         (if (not (c-in-literal lim))
  2116.             (if (memq (following-char) '(?\; ?{ ?}))
  2117.             (setq crossedp t
  2118.                   donep t)
  2119.               (if (= (following-char) ?:)
  2120.               (setq maybe-labelp t))
  2121.               (forward-char 1))
  2122.           (forward-char 1))))
  2123.         crossedp))
  2124.      ;; CASE 6: ignore labels
  2125.      ((and maybe-labelp
  2126.            (or (and c-access-key (looking-at c-access-key))
  2127.            ;; with switch labels, we have to go back further
  2128.            ;; to try to pick up the case or default
  2129.            ;; keyword. Potential bogosity alert: we assume
  2130.            ;; `case' or `default' is first thing on line
  2131.            (let ((here (point)))
  2132.              (beginning-of-line)
  2133.              (c-forward-syntactic-ws)
  2134.              (if (looking-at c-switch-label-key)
  2135.              t
  2136.                (goto-char here)
  2137.                nil))
  2138.            (looking-at c-label-key))))
  2139.      ;; CASE 7: ObjC method def
  2140.      ((and (eq major-mode 'objc-mode)
  2141.            (c-in-objc-method-def-p))
  2142.       (setq last-begin (point)
  2143.         donep t))
  2144.      ;; CASE 8: nothing special
  2145.      (t (setq last-begin (point)))
  2146.      )))
  2147.     (goto-char last-begin)
  2148.     ;; we always do want to skip over non-whitespace modifier
  2149.     ;; characters that didn't get skipped above
  2150.     (skip-chars-backward "-+!*&:.~" (c-point 'boi))))
  2151.  
  2152. (defun c-end-of-statement-1 ()
  2153.   (condition-case ()
  2154.       (progn
  2155.     (while (and (not (eobp))
  2156.             (let ((beg (point)))
  2157.               (forward-sexp 1)
  2158.               (let ((end (point)))
  2159.             (save-excursion
  2160.               (goto-char beg)
  2161.               (not (re-search-forward "[;{}]" end t)))))))
  2162.     (re-search-backward "[;}]")
  2163.     (forward-char 1))
  2164.     (error 
  2165.      (let ((beg (point)))
  2166.        (backward-up-list -1)
  2167.        (let ((end (point)))
  2168.      (goto-char beg)
  2169.      (search-forward ";" end 'move))))))
  2170.  
  2171.  
  2172. ;;(defun c-beginning-of-defun (count)
  2173. ;;  "Move the the COUNTth `real' beginning-of-defun.
  2174. ;;This is defined as the first declaration line of the most enclosing
  2175. ;;top level construct; i.e. class/struct, function, enum, etc.  With
  2176. ;;negative COUNT, go forward."
  2177. ;;  (interactive "p")
  2178. ;;  )
  2179. ;;
  2180. ;;(defun c-beginning-of-defun-1 ()
  2181. ;;  ;; move to the real beginning of defun. `Real' being defined as the
  2182. ;;  ;; first C/C++ declaration line of the most enclosing top level construct.
  2183. ;;  (let* ((state (c-parse-state))
  2184. ;;     (search-start (car state)))
  2185. ;;    ;; if the last thing is a cons then start searching from the end
  2186. ;;    ;; of the previous balanced sexp
  2187. ;;    (goto-char (or (car-safe search-start)
  2188. ;;           (and (numberp search-start)
  2189. ;;            search-start)
  2190. ;;           (point)))
  2191. ;;    (c-beginning-of-statement)
  2192. ;;    (if (bobp)
  2193. ;;    (c-forward-syntactic-ws))
  2194. ;;    ))
  2195. ;;
  2196. ;;(defun c-end-of-defun-1 ()
  2197. ;;  ;; move to the end of the defun.
  2198. ;;  (let* ((state (c-parse-state))
  2199. ;;     (search-start (car state))
  2200. ;;     )))
  2201. ;;
  2202.  
  2203. (defun c-up-conditional (count)
  2204.   "Move back to the containing preprocessor conditional, leaving mark behind.
  2205. A prefix argument acts as a repeat count.  With a negative argument,
  2206. move forward to the end of the containing preprocessor conditional.
  2207. When going backwards, `#elif' is treated like `#else' followed by
  2208. `#if'.  When going forwards, `#elif' is ignored."
  2209.   (interactive "p")
  2210.   (c-forward-conditional (- count) t)
  2211.   (c-keep-region-active))
  2212.  
  2213. (defun c-backward-conditional (count &optional up-flag)
  2214.   "Move back across a preprocessor conditional, leaving mark behind.
  2215. A prefix argument acts as a repeat count.  With a negative argument,
  2216. move forward across a preprocessor conditional."
  2217.   (interactive "p")
  2218.   (c-forward-conditional (- count) up-flag)
  2219.   (c-keep-region-active))
  2220.  
  2221. (defun c-forward-conditional (count &optional up-flag)
  2222.   "Move forward across a preprocessor conditional, leaving mark behind.
  2223. A prefix argument acts as a repeat count.  With a negative argument,
  2224. move backward across a preprocessor conditional."
  2225.   (interactive "p")
  2226.   (let* ((forward (> count 0))
  2227.      (increment (if forward -1 1))
  2228.      (search-function (if forward 're-search-forward 're-search-backward))
  2229.      (new))
  2230.     (save-excursion
  2231.       (while (/= count 0)
  2232.     (let ((depth (if up-flag 0 -1)) found)
  2233.       (save-excursion
  2234.         ;; Find the "next" significant line in the proper direction.
  2235.         (while (and (not found)
  2236.             ;; Rather than searching for a # sign that
  2237.             ;; comes at the beginning of a line aside from
  2238.             ;; whitespace, search first for a string
  2239.             ;; starting with # sign.  Then verify what
  2240.             ;; precedes it.  This is faster on account of
  2241.             ;; the fastmap feature of the regexp matcher.
  2242.             (funcall search-function
  2243.                  "#[ \t]*\\(if\\|elif\\|endif\\)"
  2244.                  nil t))
  2245.           (beginning-of-line)
  2246.           ;; Now verify it is really a preproc line.
  2247.           (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
  2248.           (let ((prev depth))
  2249.             ;; Update depth according to what we found.
  2250.             (beginning-of-line)
  2251.             (cond ((looking-at "[ \t]*#[ \t]*endif")
  2252.                (setq depth (+ depth increment)))
  2253.               ((looking-at "[ \t]*#[ \t]*elif")
  2254.                (if (and forward (= depth 0))
  2255.                    (setq found (point))))
  2256.               (t (setq depth (- depth increment))))
  2257.             ;; If we are trying to move across, and we find an
  2258.             ;; end before we find a beginning, get an error.
  2259.             (if (and (< prev 0) (< depth prev))
  2260.             (error (if forward
  2261.                    "No following conditional at this level"
  2262.                  "No previous conditional at this level")))
  2263.             ;; When searching forward, start from next line so
  2264.             ;; that we don't find the same line again.
  2265.             (if forward (forward-line 1))
  2266.             ;; If this line exits a level of conditional, exit
  2267.             ;; inner loop.
  2268.             (if (< depth 0)
  2269.             (setq found (point))))
  2270.         ;; else
  2271.         (if forward (forward-line 1))
  2272.         )))
  2273.       (or found
  2274.           (error "No containing preprocessor conditional"))
  2275.       (goto-char (setq new found)))
  2276.     (setq count (+ count increment))))
  2277.     (push-mark)
  2278.     (goto-char new))
  2279.   (c-keep-region-active))
  2280.  
  2281.  
  2282. ;; commands to indent lines, regions, defuns, and expressions
  2283. (defun c-indent-command (&optional whole-exp)
  2284.   "Indent current line as C++ code, or in some cases insert a tab character.
  2285.  
  2286. If `c-tab-always-indent' is t, always just indent the current line.
  2287. If nil, indent the current line only if point is at the left margin or
  2288. in the line's indentation; otherwise insert a tab.  If other than nil
  2289. or t, then tab is inserted only within literals (comments and strings)
  2290. and inside preprocessor directives, but line is always reindented.
  2291.  
  2292. A numeric argument, regardless of its value, means indent rigidly all
  2293. the lines of the expression starting after point so that this line
  2294. becomes properly indented.  The relative indentation among the lines
  2295. of the expression are preserved."
  2296.   (interactive "P")
  2297.   (let ((bod (c-point 'bod)))
  2298.     (if whole-exp
  2299.     ;; If arg, always indent this line as C
  2300.     ;; and shift remaining lines of expression the same amount.
  2301.     (let ((shift-amt (c-indent-line))
  2302.           beg end)
  2303.       (save-excursion
  2304.         (if (eq c-tab-always-indent t)
  2305.         (beginning-of-line))
  2306.         (setq beg (point))
  2307.         (forward-sexp 1)
  2308.         (setq end (point))
  2309.         (goto-char beg)
  2310.         (forward-line 1)
  2311.         (setq beg (point)))
  2312.       (if (> end beg)
  2313.           (indent-code-rigidly beg end (- shift-amt) "#")))
  2314.       ;; No arg supplied, use c-tab-always-indent to determine
  2315.       ;; behavior
  2316.       (cond
  2317.        ;; CASE 1: indent when at column zero or in lines indentation,
  2318.        ;; otherwise insert a tab
  2319.        ((not c-tab-always-indent)
  2320.     (if (save-excursion
  2321.           (skip-chars-backward " \t")
  2322.           (not (bolp)))
  2323.         (insert-tab)
  2324.       (c-indent-line)))
  2325.        ;; CASE 2: just indent the line
  2326.        ((eq c-tab-always-indent t)
  2327.     (c-indent-line))
  2328.        ;; CASE 3: if in a literal, insert a tab, but always indent the
  2329.        ;; line
  2330.        (t
  2331.     (if (c-in-literal bod)
  2332.         (insert-tab))
  2333.     (c-indent-line)
  2334.     )))))
  2335.  
  2336. (defun c-indent-exp (&optional shutup-p)
  2337.   "Indent each line in balanced expression following point.
  2338. Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
  2339.   (interactive "P")
  2340.   (let ((here (point))
  2341.     end)
  2342.     (unwind-protect
  2343.     (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
  2344.           (start (progn
  2345.                ;; try to be smarter about finding the range of
  2346.                ;; lines to indent. skip all following
  2347.                ;; whitespace. failing that, try to find any
  2348.                ;; opening brace on the current line
  2349.                (skip-chars-forward " \t\n")
  2350.                (if (memq (following-char) '(?\( ?\[ ?\{))
  2351.                (point)
  2352.              (let ((state (parse-partial-sexp (point)
  2353.                               (c-point 'eol))))
  2354.                (and (nth 1 state)
  2355.                 (goto-char (nth 1 state))
  2356.                 (memq (following-char) '(?\( ?\[ ?\{))
  2357.                 (point)))))))
  2358.       ;; find balanced expression end
  2359.       (setq end (and (c-safe (progn (forward-sexp 1) t))
  2360.              (point-marker)))
  2361.       ;; sanity check
  2362.       (and (not start)
  2363.            (not shutup-p)
  2364.            (error "Cannot find start of balanced expression to indent."))
  2365.       (and (not end)
  2366.            (not shutup-p)
  2367.            (error "Cannot find end of balanced expression to
  2368.            indent."))
  2369.       (c-progress-init start end 'c-indent-exp)
  2370.       (goto-char start)
  2371.       (beginning-of-line)
  2372.       (while (< (point) end)
  2373.         (if (not (looking-at "[ \t]*$"))
  2374.         (c-indent-line))
  2375.         (c-progress-update)
  2376.         (forward-line 1)))
  2377.       ;; make sure marker is deleted
  2378.       (and end
  2379.        (set-marker end nil))
  2380.       (c-progress-fini 'c-indent-exp)
  2381.       (goto-char here))))
  2382.  
  2383. (defun c-indent-defun ()
  2384.   "Re-indents the current top-level function def, struct or class declaration."
  2385.   (interactive)
  2386.   (let ((here (point-marker))
  2387.     (c-echo-syntactic-information-p nil)
  2388.     (brace (c-least-enclosing-brace (c-parse-state))))
  2389.     (if brace
  2390.     (goto-char brace)
  2391.       (beginning-of-defun))
  2392.     ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
  2393.     ;; the open brace. I consider this an Emacs bug.
  2394.     (and (boundp 'defun-prompt-regexp)
  2395.      defun-prompt-regexp
  2396.      (looking-at defun-prompt-regexp)
  2397.      (goto-char (match-end 0)))
  2398.     ;; catch all errors in c-indent-exp so we can 1. give more
  2399.     ;; meaningful error message, and 2. restore point
  2400.     (unwind-protect
  2401.     (c-indent-exp)
  2402.       (goto-char here)
  2403.       (set-marker here nil))))
  2404.  
  2405. (defun c-indent-region (start end)
  2406.   ;; Indent every line whose first char is between START and END inclusive.
  2407.   (save-excursion
  2408.     (goto-char start)
  2409.     ;; Advance to first nonblank line.
  2410.     (skip-chars-forward " \t\n")
  2411.     (beginning-of-line)
  2412.     (let (endmark)
  2413.       (unwind-protect
  2414.       (let ((c-tab-always-indent t)
  2415.         ;; shut up any echo msgs on indiv lines
  2416.         (c-echo-syntactic-information-p nil))
  2417.         (c-progress-init start end 'c-indent-region)
  2418.         (setq endmark (copy-marker end))
  2419.         (while (and (bolp)
  2420.             (not (eobp))
  2421.             (< (point) endmark))
  2422.           ;; update progress
  2423.           (c-progress-update)
  2424.           ;; Indent one line as with TAB.
  2425.           (let (nextline sexpend sexpbeg)
  2426.         ;; skip blank lines
  2427.         (skip-chars-forward " \t\n")
  2428.         (beginning-of-line)
  2429.         ;; indent the current line
  2430.         (c-indent-line)
  2431.         (if (save-excursion
  2432.               (beginning-of-line)
  2433.               (looking-at "[ \t]*#"))
  2434.             (forward-line 1)
  2435.           (save-excursion
  2436.             ;; Find beginning of following line.
  2437.             (setq nextline (c-point 'bonl))
  2438.             ;; Find first beginning-of-sexp for sexp extending past
  2439.             ;; this line.
  2440.             (beginning-of-line)
  2441.             (while (< (point) nextline)
  2442.               (condition-case nil
  2443.               (progn
  2444.                 (forward-sexp 1)
  2445.                 (setq sexpend (point)))
  2446.             (error (setq sexpend nil)
  2447.                    (goto-char nextline)))
  2448.               (c-forward-syntactic-ws))
  2449.             (if sexpend
  2450.             (progn 
  2451.               ;; make sure the sexp we found really starts on the
  2452.               ;; current line and extends past it
  2453.               (goto-char sexpend)
  2454.               (setq sexpend (point-marker))
  2455.               (backward-sexp 1)
  2456.               (setq sexpbeg (point)))))
  2457.           ;; check to see if the next line starts a
  2458.           ;; comment-only line
  2459.           (save-excursion
  2460.             (forward-line 1)
  2461.             (skip-chars-forward " \t")
  2462.             (if (looking-at c-comment-start-regexp)
  2463.             (setq sexpbeg (c-point 'bol))))
  2464.           ;; If that sexp ends within the region, indent it all at
  2465.           ;; once, fast.
  2466.           (condition-case nil
  2467.               (if (and sexpend
  2468.                    (> sexpend nextline)
  2469.                    (<= sexpend endmark))
  2470.               (progn
  2471.                 (goto-char sexpbeg)
  2472.                 (c-indent-exp 'shutup)
  2473.                 (c-progress-update)
  2474.                 (goto-char sexpend)))
  2475.             (error
  2476.              (goto-char sexpbeg)
  2477.              (c-indent-line)))
  2478.           ;; Move to following line and try again.
  2479.           (and sexpend
  2480.                (markerp sexpend)
  2481.                (set-marker sexpend nil))
  2482.           (forward-line 1)))))
  2483.     (set-marker endmark nil)
  2484.     (c-progress-fini 'c-indent-region)
  2485.     ))))
  2486.  
  2487. (defun c-mark-function ()
  2488.   "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
  2489.   (interactive)
  2490.   (let ((here (point))
  2491.     ;; there should be a c-point position for 'eod
  2492.     (eod  (save-excursion (end-of-defun) (point)))
  2493.     (state (c-parse-state))
  2494.     brace)
  2495.     (while state
  2496.       (setq brace (car state))
  2497.       (if (consp brace)
  2498.       (goto-char (cdr brace))
  2499.     (goto-char brace))
  2500.       (setq state (cdr state)))
  2501.     (if (= (following-char) ?{)
  2502.     (progn
  2503.       (forward-line -1)
  2504.       (while (not (or (bobp)
  2505.               (looking-at "[ \t]*$")))
  2506.         (forward-line -1)))
  2507.       (forward-line 1)
  2508.       (skip-chars-forward " \t\n"))
  2509.     (push-mark here)
  2510.     (push-mark eod nil t)))
  2511.  
  2512.  
  2513. ;; for progress reporting
  2514. (defvar c-progress-info nil)
  2515.  
  2516. (defun c-progress-init (start end context)
  2517.   ;; start the progress update messages.  if this emacs doesn't have a
  2518.   ;; built-in timer, just be dumb about it
  2519.   (if (not (fboundp 'current-time))
  2520.       (message "indenting region... (this may take a while)")
  2521.     ;; if progress has already been initialized, do nothing. otherwise
  2522.     ;; initialize the counter with a vector of:
  2523.     ;; [start end lastsec context]
  2524.     (if c-progress-info
  2525.     ()
  2526.       (setq c-progress-info (vector start
  2527.                     (save-excursion
  2528.                       (goto-char end)
  2529.                       (point-marker))
  2530.                     (nth 1 (current-time))
  2531.                     context))
  2532.       (message "indenting region..."))))
  2533.  
  2534. (defun c-progress-update ()
  2535.   ;; update progress
  2536.   (if (not (and c-progress-info c-progress-interval))
  2537.       nil
  2538.     (let ((now (nth 1 (current-time)))
  2539.       (start (aref c-progress-info 0))
  2540.       (end (aref c-progress-info 1))
  2541.       (lastsecs (aref c-progress-info 2)))
  2542.       ;; should we update?  currently, update happens every 2 seconds,
  2543.       ;; what's the right value?
  2544.       (if (< c-progress-interval (- now lastsecs))
  2545.       (progn
  2546.         (message "indenting region... (%d%% complete)"
  2547.              (/ (* 100 (- (point) start)) (- end start)))
  2548.         (aset c-progress-info 2 now)))
  2549.       )))
  2550.  
  2551. (defun c-progress-fini (context)
  2552.   ;; finished
  2553.   (if (or (eq context (aref c-progress-info 3))
  2554.       (eq context t))
  2555.       (progn
  2556.     (set-marker (aref c-progress-info 1) nil)
  2557.     (setq c-progress-info nil)
  2558.     (message "indenting region... done."))))
  2559.  
  2560.  
  2561. ;; Skipping of "syntactic whitespace" for Emacs 19.  Syntactic
  2562. ;; whitespace is defined as lexical whitespace, C and C++ style
  2563. ;; comments, and preprocessor directives.  Search no farther back or
  2564. ;; forward than optional LIM.  If LIM is omitted, `beginning-of-defun'
  2565. ;; is used for backward skipping, point-max is used for forward
  2566. ;; skipping.  Note that Emacs 18 support has been moved to cc-mode-18.el.
  2567.  
  2568. (defun c-forward-syntactic-ws (&optional lim)
  2569.   ;; Forward skip of syntactic whitespace for Emacs 19.
  2570.   (save-restriction
  2571.     (let* ((lim (or lim (point-max)))
  2572.        (here lim)
  2573.        (hugenum (point-max)))
  2574.       (narrow-to-region lim (point))
  2575.       (while (/= here (point))
  2576.     (setq here (point))
  2577.     (forward-comment hugenum)
  2578.     ;; skip preprocessor directives
  2579.     (if (and (= (following-char) ?#)
  2580.          (= (c-point 'boi) (point)))
  2581.         (end-of-line)
  2582.       )))))
  2583.  
  2584. (defun c-backward-syntactic-ws (&optional lim)
  2585.   ;; Backward skip over syntactic whitespace for Emacs 19.
  2586.   (save-restriction
  2587.     (let* ((lim (or lim (c-point 'bod)))
  2588.        (here lim)
  2589.        (hugenum (- (point-max))))
  2590.       (if (< lim (point))
  2591.       (progn
  2592.         (narrow-to-region lim (point))
  2593.         (while (/= here (point))
  2594.           (setq here (point))
  2595.           (forward-comment hugenum)
  2596.           (if (eq (c-in-literal lim) 'pound)
  2597.           (beginning-of-line))
  2598.           )))
  2599.       )))
  2600.  
  2601.  
  2602. ;; Return `c' if in a C-style comment, `c++' if in a C++ style
  2603. ;; comment, `string' if in a string literal, `pound' if on a
  2604. ;; preprocessor line, or nil if not in a comment at all.  Optional LIM
  2605. ;; is used as the backward limit of the search.  If omitted, or nil,
  2606. ;; `beginning-of-defun' is used."
  2607.  
  2608. ;; This is for all v19 Emacsen supporting either 1-bit or 8-bit syntax
  2609. (defun c-in-literal (&optional lim)
  2610.   ;; Determine if point is in a C++ literal. we cache the last point
  2611.   ;; calculated if the cache is enabled
  2612.   (if (and (boundp 'c-in-literal-cache)
  2613.        c-in-literal-cache
  2614.        (= (point) (aref c-in-literal-cache 0)))
  2615.       (aref c-in-literal-cache 1)
  2616.     (let ((rtn (save-excursion
  2617.          (let* ((lim (or lim (c-point 'bod)))
  2618.             (here (point))
  2619.             (state (parse-partial-sexp lim (point))))
  2620.            (cond
  2621.             ((nth 3 state) 'string)
  2622.             ((nth 4 state) (if (nth 7 state) 'c++ 'c))
  2623.             ((progn
  2624.                (goto-char here)
  2625.                (beginning-of-line)
  2626.                (looking-at "[ \t]*#"))
  2627.              'pound)
  2628.             (t nil))))))
  2629.       ;; cache this result if the cache is enabled
  2630.       (and (boundp 'c-in-literal-cache)
  2631.        (setq c-in-literal-cache (vector (point) rtn)))
  2632.       rtn)))
  2633.  
  2634.  
  2635. ;; utilities for moving and querying around syntactic elements
  2636. (defun c-parse-state ()
  2637.   ;; Finds and records all open parens between some important point
  2638.   ;; earlier in the file and point.
  2639.   (let* (at-bob placeholder
  2640.      (pos (save-excursion
  2641.         ;; go back 2 bods, but ignore any bogus positions
  2642.         ;; returned by beginning-of-defun (i.e. open paren in
  2643.         ;; column zero)
  2644.         (let ((cnt 0))
  2645.           (while (and (not at-bob) (< cnt 2))
  2646.             (beginning-of-defun)
  2647.             (if (= (following-char) ?\{)
  2648.             (setq cnt (1+ cnt)))
  2649.             (if (bobp)
  2650.             (setq at-bob t))))
  2651.         (point)))
  2652.      (here (save-excursion
  2653.          ;;(skip-chars-forward " \t}")
  2654.          (point)))
  2655.      (last-bod pos) (last-pos pos) state sexp-end)
  2656.     ;; cache last bod position
  2657.     (while (catch 'backup-bod
  2658.          (setq state nil)
  2659.          (while (and pos (< pos here))
  2660.            (setq last-pos pos)
  2661.            (if (and (setq pos (c-safe (scan-lists pos 1 -1)))
  2662.             (<= pos here))
  2663.            (progn
  2664.              (setq sexp-end (c-safe (scan-sexps (1- pos) 1)))
  2665.              (if (and sexp-end
  2666.                   (<= sexp-end here))
  2667.              ;; we want to record both the start and end
  2668.              ;; of this sexp, but we only want to record
  2669.              ;; the last-most of any of them before here
  2670.              (progn
  2671.                (if (= (char-after (1- pos)) ?\{)
  2672.                    (setq state (cons (cons (1- pos) sexp-end)
  2673.                          (if (consp (car state))
  2674.                              (cdr state)
  2675.                            state))))
  2676.                (setq pos sexp-end))
  2677.                ;; we're contained in this sexp so put pos on
  2678.                ;; front of list
  2679.                (setq state (cons (1- pos) state))))
  2680.          ;; something bad happened. check to see if we crossed
  2681.          ;; an unbalanced close brace. if so, we didn't really
  2682.          ;; find the right `important bufpos' so lets back up
  2683.          ;; and try again
  2684.          (if (and (not pos) (not at-bob)
  2685.               (setq placeholder (c-safe (scan-lists last-pos 1 1)))
  2686.               ;;(char-after (1- placeholder))
  2687.               (<= placeholder here)
  2688.               (= (char-after (1- placeholder)) ?\}))
  2689.              (while t
  2690.                (setq last-bod (c-safe (scan-lists last-bod -1 1)))
  2691.                (if (not last-bod)
  2692.                (error "unbalanced close brace found at position %d"
  2693.                   (1- placeholder))
  2694.              (setq at-bob (= last-bod (point-min))
  2695.                    pos last-bod)
  2696.              (if (= (char-after last-bod) ?\{)
  2697.                  (throw 'backup-bod t)))
  2698.                ))        ;end-if
  2699.          ))            ;end-while
  2700.          nil))
  2701.     state))
  2702.  
  2703. (defun c-beginning-of-inheritance-list (&optional lim)
  2704.   ;; Go to the first non-whitespace after the colon that starts a
  2705.   ;; multiple inheritance introduction.  Optional LIM is the farthest
  2706.   ;; back we should search.
  2707.   (let ((lim (or lim (c-point 'bod)))
  2708.     (placeholder (progn
  2709.                (back-to-indentation)
  2710.                (point))))
  2711.     (c-backward-syntactic-ws lim)
  2712.     (while (and (> (point) lim)
  2713.         (memq (preceding-char) '(?, ?:))
  2714.         (progn
  2715.           (beginning-of-line)
  2716.           (setq placeholder (point))
  2717.           (skip-chars-forward " \t")
  2718.           (not (looking-at c-class-key))
  2719.           ))
  2720.       (c-backward-syntactic-ws lim))
  2721.     (goto-char placeholder)
  2722.     (skip-chars-forward "^:" (c-point 'eol))))
  2723.  
  2724. (defun c-beginning-of-macro (&optional lim)
  2725.   ;; Go to the beginning of the macro. Right now we don't support
  2726.   ;; multi-line macros too well
  2727.   (back-to-indentation))
  2728.  
  2729. (defun c-in-objc-method-def-p ()
  2730.   ;; Return nil if we aren't in a method definition, otherwise the
  2731.   ;; position of the initial [+-].
  2732.   (save-excursion
  2733.     (c-backward-syntactic-ws)
  2734.     (if (or (= (preceding-char) ?-)
  2735.         (= (preceding-char) ?+))
  2736.     (let ((initial-pos (1- (point))))
  2737.       (beginning-of-line)
  2738.       (if (looking-at c-ObjC-method-key)
  2739.           initial-pos))
  2740.       nil)))
  2741.  
  2742. (defun c-just-after-func-arglist-p (&optional containing)
  2743.   ;; Return t if we are between a function's argument list closing
  2744.   ;; paren and its opening brace.  Note that the list close brace
  2745.   ;; could be followed by a "const" specifier or a member init hanging
  2746.   ;; colon.  Optional CONTAINING is position of containing s-exp open
  2747.   ;; brace.  If not supplied, point is used as search start.
  2748.   (save-excursion
  2749.     (c-backward-syntactic-ws)
  2750.     (let ((checkpoint (or containing (point))))
  2751.       (goto-char checkpoint)
  2752.       ;; could be looking at const specifier
  2753.       (if (and (= (preceding-char) ?t)
  2754.            (forward-word -1)
  2755.            (looking-at "\\<const\\>"))
  2756.       (c-backward-syntactic-ws)
  2757.     ;; otherwise, we could be looking at a hanging member init
  2758.     ;; colon
  2759.     (goto-char checkpoint)
  2760.     (if (and (= (preceding-char) ?:)
  2761.          (progn
  2762.            (forward-char -1)
  2763.            (c-backward-syntactic-ws)
  2764.            (looking-at "[ \t\n]*:\\([^:]+\\|$\\)")))
  2765.         nil
  2766.       (goto-char checkpoint))
  2767.     )
  2768.       (and (= (preceding-char) ?\))
  2769.        ;; check if we are looking at a method def
  2770.        (or (not (eq major-mode 'objc-mode))
  2771.            (progn
  2772.          (forward-sexp -1)
  2773.          (forward-char -1)
  2774.          (c-backward-syntactic-ws)
  2775.          (not (or (= (preceding-char) ?-)
  2776.               (= (preceding-char) ?+)
  2777.               ;; or a class category
  2778.               (progn
  2779.                 (forward-sexp -2)
  2780.                 (looking-at c-class-key))
  2781.               )))))
  2782.       )))
  2783.  
  2784. ;; defuns to look backwards for things
  2785. (defun c-backward-to-start-of-do (&optional lim)
  2786.   ;; Move to the start of the last "unbalanced" do expression.
  2787.   ;; Optional LIM is the farthest back to search.
  2788.   (let ((do-level 1)
  2789.     (case-fold-search nil)
  2790.     (lim (or lim (c-point 'bod))))
  2791.     (while (not (zerop do-level))
  2792.       ;; we protect this call because trying to execute this when the
  2793.       ;; while is not associated with a do will throw an error
  2794.       (condition-case nil
  2795.       (progn
  2796.         (backward-sexp 1)
  2797.         (cond
  2798.          ((memq (c-in-literal lim) '(c c++)))
  2799.          ((looking-at "while\\b[^_]")
  2800.           (setq do-level (1+ do-level)))
  2801.          ((looking-at "do\\b[^_]")
  2802.           (setq do-level (1- do-level)))
  2803.          ((< (point) lim)
  2804.           (setq do-level 0)
  2805.           (goto-char lim))))
  2806.     (error
  2807.      (goto-char lim)
  2808.      (setq do-level 0))))))
  2809.  
  2810. (defun c-backward-to-start-of-if (&optional lim)
  2811.   ;; Move to the start of the last "unbalanced" if and return t.  If
  2812.   ;; none is found, and we are looking at an if clause, nil is
  2813.   ;; returned.  If none is found and we are looking at an else clause,
  2814.   ;; an error is thrown.
  2815.   (let ((if-level 1)
  2816.     (case-fold-search nil)
  2817.     (lim (or lim (c-point 'bod)))
  2818.     (at-if (looking-at "if\\b[^_]")))
  2819.     (catch 'orphan-if
  2820.       (while (and (not (bobp))
  2821.           (not (zerop if-level)))
  2822.     (c-backward-syntactic-ws)
  2823.     (condition-case nil
  2824.         (backward-sexp 1)
  2825.       (error
  2826.        (if at-if
  2827.            (throw 'orphan-if nil)
  2828.          (error "Orphaned `else' clause encountered."))))
  2829.     (cond
  2830.      ((looking-at "else\\b[^_]")
  2831.       (setq if-level (1+ if-level)))
  2832.      ((looking-at "if\\b[^_]")
  2833.       ;; check for else if... skip over
  2834.       (let ((here (point)))
  2835.         (c-safe (forward-sexp -1))
  2836.         (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  2837.         nil
  2838.           (setq if-level (1- if-level))
  2839.           (goto-char here))))
  2840.      ((< (point) lim)
  2841.       (setq if-level 0)
  2842.       (goto-char lim))
  2843.      ))
  2844.       t)))
  2845.  
  2846. (defun c-skip-conditional ()
  2847.   ;; skip forward over conditional at point, including any predicate
  2848.   ;; statements in parentheses. No error checking is performed.
  2849.   (forward-sexp
  2850.    ;; else if()
  2851.    (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  2852.        3
  2853.      ;; do and else aren't followed by parens
  2854.      (if (looking-at "\\<\\(do\\|else\\)\\>")
  2855.      1 2))))
  2856.  
  2857. (defun c-skip-case-statement-forward (&optional lim)
  2858.   ;; skip forward over case/default bodies, with optional maximal
  2859.   ;; limit. if no next case body is found, nil is returned and point
  2860.   ;; is not moved
  2861.   (let ((lim (or lim (point-max)))
  2862.     (here (point))
  2863.     donep foundp)
  2864.     (while (and (< (point) lim)
  2865.         (not donep))
  2866.       (if (and (re-search-forward c-switch-label-key lim 'move)
  2867.            (save-match-data
  2868.          (not (c-in-literal)))
  2869.            (/= (match-beginning 0) here))
  2870.       (progn
  2871.         (goto-char (match-beginning 0))
  2872.         (setq donep t
  2873.           foundp t))))
  2874.     (if (not foundp)
  2875.     (goto-char here))
  2876.     foundp))
  2877.  
  2878. (defun c-search-uplist-for-classkey (brace-state)
  2879.   ;; search for the containing class, returning a 2 element vector if
  2880.   ;; found. aref 0 contains the bufpos of the class key, and aref 1
  2881.   ;; contains the bufpos of the open brace.
  2882.   (if (null brace-state)
  2883.       ;; no brace-state means we cannot be inside a class
  2884.       nil
  2885.     (let ((carcache (car brace-state))
  2886.       search-start search-end)
  2887.       (if (consp carcache)
  2888.       ;; a cons cell in the first element means that there is some
  2889.       ;; balanced sexp before the current bufpos. this we can
  2890.       ;; ignore. the nth 1 and nth 2 elements define for us the
  2891.       ;; search boundaries
  2892.       (setq search-start (nth 2 brace-state)
  2893.         search-end (nth 1 brace-state))
  2894.     ;; if the car was not a cons cell then nth 0 and nth 1 define
  2895.     ;; for us the search boundaries
  2896.     (setq search-start (nth 1 brace-state)
  2897.           search-end (nth 0 brace-state)))
  2898.       ;; search-end cannot be a cons cell
  2899.       (and (consp search-end)
  2900.        (error "consp search-end: %s" search-end))
  2901.       ;; if search-end is nil, or if the search-end character isn't an
  2902.       ;; open brace, we are definitely not in a class
  2903.       (if (or (not search-end)
  2904.           (/= (char-after search-end) ?{))
  2905.       nil
  2906.     ;; now, we need to look more closely at search-start.  if
  2907.     ;; search-start is nil, then our start boundary is really
  2908.     ;; point-min.
  2909.     (if (not search-start)
  2910.         (setq search-start (point-min))
  2911.       ;; if search-start is a cons cell, then we can start
  2912.       ;; searching from the end of the balanced sexp just ahead of
  2913.       ;; us
  2914.       (if (consp search-start)
  2915.           (setq search-start (cdr search-start))))
  2916.     ;; now we can do a quick regexp search from search-start to
  2917.     ;; search-end and see if we can find a class key.  watch for
  2918.     ;; class like strings in literals
  2919.     (save-excursion
  2920.       (save-restriction
  2921.         (goto-char search-start)
  2922.         (let (foundp class)
  2923.           (while (and (not foundp)
  2924.               (progn
  2925.                 (c-forward-syntactic-ws)
  2926.                 (> search-end (point)))
  2927.               (re-search-forward c-class-key search-end t))
  2928.         (setq class (match-beginning 0))
  2929.         (if (c-in-literal search-start)
  2930.             nil            ; its in a comment or string, ignore
  2931.           (goto-char class)
  2932.           (skip-chars-forward " \t\n")
  2933.           (setq foundp (vector (c-point 'boi) search-end))
  2934.           ;; make sure we're really looking at the start of
  2935.           ;; a class definition, and not a forward decl,
  2936.           ;; return arg, template arg list, or an ObjC method.
  2937.           (if (eq major-mode 'objc-mode)
  2938.               (if (re-search-forward c-ObjC-method-key search-end t)
  2939.               (setq foundp nil))
  2940.             ;; Its impossible to define a regexp for this, and
  2941.             ;; nearly so to do it programmatically.
  2942.             ;;
  2943.             ;; ; picks up forward decls
  2944.             ;; = picks up init lists
  2945.             ;; ) picks up return types
  2946.             ;; > picks up templates, but remember that we can
  2947.             ;;   inherit from templates!
  2948.             (let ((skipchars "^;=)"))
  2949.               ;; try to see if we found the `class' keyword
  2950.               ;; inside a template arg list
  2951.               (save-excursion
  2952.             (skip-chars-backward "^<" search-start)
  2953.             (if (= (preceding-char) ?<)
  2954.                 (setq skipchars (concat skipchars ">"))))
  2955.               (skip-chars-forward skipchars search-end)
  2956.               (if (/= (point) search-end)
  2957.               (setq foundp nil))
  2958.               ))))
  2959.           foundp))
  2960.       )))))
  2961.  
  2962. (defun c-inside-bracelist-p (containing-sexp brace-state)
  2963.   ;; return the buffer position of the beginning of the brace list
  2964.   ;; statement if we're inside a brace list, otherwise return nil.
  2965.   ;; CONTAINING-SEXP is the buffer pos of the innermost containing
  2966.   ;; paren. BRACE-STATE is the remainder of the state of enclosing braces
  2967.   (or
  2968.    ;; this will pick up enum lists
  2969.    (save-excursion
  2970.      (goto-char containing-sexp)
  2971.      (c-beginning-of-statement)
  2972.      ;; c-b-o-s could have left us at point-min
  2973.      (and (bobp)
  2974.       (c-forward-syntactic-ws))
  2975.      (if (and (< (point) containing-sexp)
  2976.           (looking-at "\\(typedef[ \t]+\\)?enum[ \t\n]+")
  2977.           (save-excursion
  2978.         (skip-chars-forward "^;(" containing-sexp)
  2979.         (= (point) containing-sexp)))
  2980.      (point)))
  2981.    ;; this will pick up array/aggregate init lists, even if they are nested.
  2982.    (save-excursion
  2983.      (let (bufpos)
  2984.        (while (and (not bufpos)
  2985.            containing-sexp)
  2986.      (if (consp containing-sexp)
  2987.          (setq containing-sexp (car brace-state)
  2988.            brace-state (cdr brace-state))
  2989.        (goto-char containing-sexp)
  2990.        (c-backward-syntactic-ws)
  2991.        (if (/= (preceding-char) ?=)
  2992.            ;; lets see if we're nested. find the most nested
  2993.            ;; containing brace
  2994.            (setq containing-sexp (car brace-state)
  2995.              brace-state (cdr brace-state))
  2996.          ;; we've hit the beginning of the aggregate list
  2997.          (c-beginning-of-statement)
  2998.          (setq bufpos (point)))
  2999.        ))
  3000.        bufpos))
  3001.    ))
  3002.  
  3003.  
  3004. ;; defuns for calculating the syntactic state and indenting a single
  3005. ;; line of C/C++/ObjC code
  3006. (defmacro c-add-syntax (symbol &optional relpos)
  3007.   ;; a simple macro to append the syntax in symbol to the syntax list.
  3008.   ;; try to increase performance by using this macro
  3009.   (` (setq syntax (cons (cons (, symbol) (, relpos)) syntax))))
  3010.  
  3011. (defun c-most-enclosing-brace (state)
  3012.   ;; return the bufpos of the most enclosing brace that hasn't been
  3013.   ;; narrowed out by any enclosing class, or nil if none was found
  3014.   (let (enclosingp)
  3015.     (while (and state (not enclosingp))
  3016.       (setq enclosingp (car state)
  3017.         state (cdr state))
  3018.       (if (consp enclosingp)
  3019.       (setq enclosingp nil)
  3020.     (if (> (point-min) enclosingp)
  3021.         (setq enclosingp nil))
  3022.     (setq state nil)))
  3023.     enclosingp))
  3024.  
  3025. (defun c-least-enclosing-brace (state)
  3026.   ;; return the bufpos of the least (highest) enclosing brace that
  3027.   ;; hasn't been narrowed out by any enclosing class, or nil if none
  3028.   ;; was found.
  3029.   (c-most-enclosing-brace (nreverse state)))
  3030.  
  3031. (defun c-narrow-out-enclosing-class (state lim)
  3032.   ;; narrow the buffer so that the enclosing class is hidden
  3033.   (let (inclass-p)
  3034.     (and state
  3035.      (setq inclass-p (c-search-uplist-for-classkey state))
  3036.      (narrow-to-region
  3037.       (progn
  3038.         (goto-char (1+ (aref inclass-p 1)))
  3039.         (skip-chars-forward " \t\n" lim)
  3040.         ;; if point is now left of the class opening brace, we're
  3041.         ;; hosed, so try a different tact
  3042.         (if (<= (c-point 'bol) (aref inclass-p 1))
  3043.         (progn
  3044.           (goto-char (1+ (aref inclass-p 1)))
  3045.           (c-forward-syntactic-ws lim)))
  3046.         (c-point 'bol))
  3047.       ;; end point is the end of the current line
  3048.       (progn
  3049.         (goto-char lim)
  3050.         (c-point 'eol))))
  3051.     ;; return the class vector
  3052.     inclass-p))
  3053.  
  3054. (defun c-guess-basic-syntax ()
  3055.   ;; guess the syntactic description of the current line of C++ code.
  3056.   (save-excursion
  3057.     (save-restriction
  3058.       (beginning-of-line)
  3059.       (let* ((indent-point (point))
  3060.          (case-fold-search nil)
  3061.          (state (c-parse-state))
  3062.          (in-method-intro-p (and (eq major-mode 'objc-mode)
  3063.                      (looking-at c-ObjC-method-key)))
  3064.          literal containing-sexp char-before-ip char-after-ip lim
  3065.          syntax placeholder c-in-literal-cache
  3066.          ;; narrow out any enclosing class
  3067.          (inclass-p (c-narrow-out-enclosing-class state indent-point))
  3068.          )
  3069.  
  3070.     ;; get the buffer position of the most nested opening brace,
  3071.     ;; if there is one, and it hasn't been narrowed out
  3072.     (save-excursion
  3073.       (goto-char indent-point)
  3074.       (skip-chars-forward " \t}")
  3075.       (skip-chars-backward " \t")
  3076.       (while (and state
  3077.               (not in-method-intro-p)
  3078.               (not containing-sexp))
  3079.         (setq containing-sexp (car state)
  3080.           state (cdr state))
  3081.         (if (consp containing-sexp)
  3082.         ;; if cdr == point, then containing sexp is the brace
  3083.         ;; that opens the sexp we close
  3084.         (if (= (cdr containing-sexp) (point))
  3085.             (setq containing-sexp (car containing-sexp))
  3086.           ;; otherwise, ignore this element
  3087.           (setq containing-sexp nil))
  3088.           ;; ignore the bufpos if its been narrowed out by the
  3089.           ;; containing class
  3090.           (if (<= containing-sexp (point-min))
  3091.           (setq containing-sexp nil)))))
  3092.  
  3093.     ;; set the limit on the farthest back we need to search
  3094.     (setq lim (or containing-sexp (point-min)))
  3095.  
  3096.     ;; cache char before and after indent point, and move point to
  3097.     ;; the most likely position to perform the majority of tests
  3098.     (goto-char indent-point)
  3099.     (skip-chars-forward " \t")
  3100.     (setq char-after-ip (following-char))
  3101.     (c-backward-syntactic-ws lim)
  3102.     (setq char-before-ip (preceding-char))
  3103.     (goto-char indent-point)
  3104.     (skip-chars-forward " \t")
  3105.  
  3106.     ;; are we in a literal?
  3107.     (setq literal (c-in-literal lim))
  3108.  
  3109.     ;; now figure out syntactic qualities of the current line
  3110.     (cond
  3111.      ;; CASE 1: in a string.
  3112.      ((memq literal '(string))
  3113.       (c-add-syntax 'string (c-point 'bopl)))
  3114.      ;; CASE 2: in a C or C++ style comment.
  3115.      ((memq literal '(c c++))
  3116.       ;; we need to catch multi-paragraph C comments
  3117.       (while (and (zerop (forward-line -1))
  3118.               (looking-at "^[ \t]*$")))
  3119.       (c-add-syntax literal (c-point 'bol)))
  3120.      ;; CASE 3: in a cpp preprocessor
  3121.      ((eq literal 'pound)
  3122.       (c-beginning-of-macro lim)
  3123.       (c-add-syntax 'cpp-macro (c-point 'boi)))
  3124.      ;; CASE 4: in an objective-c method intro
  3125.      (in-method-intro-p
  3126.       (c-add-syntax 'objc-method-intro (c-point 'boi)))
  3127.      ;; CASE 5: Line is at top level.
  3128.      ((null containing-sexp)
  3129.       (cond
  3130.        ;; CASE 5A: we are looking at a defun, class, or
  3131.        ;; inline-inclass method opening brace
  3132.        ((= char-after-ip ?{)
  3133.         (cond
  3134.          ;; CASE 5A.1: we are looking at a class opening brace
  3135.          ((save-excursion
  3136.         (goto-char indent-point)
  3137.         (skip-chars-forward " \t{")
  3138.         (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  3139.           (and decl
  3140.                (setq placeholder (aref decl 0)))
  3141.           ))
  3142.           (c-add-syntax 'class-open placeholder))
  3143.          ;; CASE 5A.2: brace list open
  3144.          ((save-excursion
  3145.         (c-beginning-of-statement nil lim)
  3146.         ;; c-b-o-s could have left us at point-min
  3147.         (and (bobp)
  3148.              (c-forward-syntactic-ws indent-point))
  3149.         (setq placeholder (point))
  3150.         (and (or (looking-at "enum[ \t\n]+")
  3151.              (= char-before-ip ?=))
  3152.              (save-excursion
  3153.                (skip-chars-forward "^;" indent-point)
  3154.                (/= (following-char) ?\;))))
  3155.           (c-add-syntax 'brace-list-open placeholder))
  3156.          ;; CASE 5A.3: inline defun open
  3157.          (inclass-p
  3158.           (c-add-syntax 'inline-open (aref inclass-p 0)))
  3159.          ;; CASE 5A.4: ordinary defun open
  3160.          (t
  3161.           (goto-char placeholder)
  3162.           (c-add-syntax 'defun-open (c-point 'bol))
  3163.           )))
  3164.        ;; CASE 5B: first K&R arg decl or member init
  3165.        ((c-just-after-func-arglist-p)
  3166.         (cond
  3167.          ;; CASE 5B.1: a member init
  3168.          ((or (= char-before-ip ?:)
  3169.           (= char-after-ip ?:))
  3170.           ;; this line should be indented relative to the beginning
  3171.           ;; of indentation for the topmost-intro line that contains
  3172.           ;; the prototype's open paren
  3173.           ;; TBD: is the following redundant?
  3174.           (if (= char-before-ip ?:)
  3175.           (forward-char -1))
  3176.           (c-backward-syntactic-ws lim)
  3177.           ;; TBD: is the preceding redundant?
  3178.           (if (= (preceding-char) ?:)
  3179.           (progn (forward-char -1)
  3180.              (c-backward-syntactic-ws lim)))
  3181.           (if (= (preceding-char) ?\))
  3182.           (backward-sexp 1))
  3183.           (c-add-syntax 'member-init-intro (c-point 'boi))
  3184.           ;; we don't need to add any class offset since this
  3185.           ;; should be relative to the ctor's indentation
  3186.           )
  3187.          ;; CASE 5B.2: K&R arg decl intro
  3188.          (c-recognize-knr-p
  3189.           (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
  3190.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3191.          ;; CASE 5B.3: nether region after a C++ func decl
  3192.          (t
  3193.           (c-add-syntax 'ansi-funcdecl-cont (c-point 'boi))
  3194.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3195.          ))
  3196.        ;; CASE 5C: inheritance line. could be first inheritance
  3197.        ;; line, or continuation of a multiple inheritance
  3198.        ((looking-at c-baseclass-key)
  3199.         (cond
  3200.          ;; CASE 5C.1: non-hanging colon on an inher intro
  3201.          ((= char-after-ip ?:)
  3202.           (c-backward-syntactic-ws lim)
  3203.           (c-add-syntax 'inher-intro (c-point 'boi))
  3204.           ;; don't add inclass symbol since relative point already
  3205.           ;; contains any class offset
  3206.           )
  3207.          ;; CASE 5C.2: hanging colon on an inher intro
  3208.          ((= char-before-ip ?:)
  3209.           (c-add-syntax 'inher-intro (c-point 'boi))
  3210.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3211.          ;; CASE 5C.3: a continued inheritance line
  3212.          (t
  3213.           (c-beginning-of-inheritance-list lim)
  3214.           (c-add-syntax 'inher-cont (point))
  3215.           ;; don't add inclass symbol since relative point already
  3216.           ;; contains any class offset
  3217.           )))
  3218.        ;; CASE 5D: this could be a top-level compound statement or a
  3219.        ;; member init list continuation
  3220.        ((= char-before-ip ?,)
  3221.         (goto-char indent-point)
  3222.         (c-backward-syntactic-ws lim)
  3223.         (while (and (< lim (point))
  3224.             (= (preceding-char) ?,))
  3225.           ;; this will catch member inits with multiple
  3226.           ;; line arglists
  3227.           (forward-char -1)
  3228.           (c-backward-syntactic-ws (c-point 'bol))
  3229.           (if (= (preceding-char) ?\))
  3230.           (backward-sexp 1))
  3231.           ;; now continue checking
  3232.           (beginning-of-line)
  3233.           (c-backward-syntactic-ws lim))
  3234.         (cond
  3235.          ;; CASE 5D.1: hanging member init colon
  3236.          ((= (preceding-char) ?:)
  3237.           (goto-char indent-point)
  3238.           (c-backward-syntactic-ws lim)
  3239.           (c-safe (backward-sexp 1))
  3240.           (c-add-syntax 'member-init-cont (c-point 'boi))
  3241.           ;; we do not need to add class offset since relative
  3242.           ;; point is the member init above us
  3243.           )
  3244.          ;; CASE 5D.2: non-hanging member init colon
  3245.          ((progn
  3246.         (c-forward-syntactic-ws indent-point)
  3247.         (= (following-char) ?:))
  3248.           (skip-chars-forward " \t:")
  3249.           (c-add-syntax 'member-init-cont (point)))
  3250.          ;; CASE 5D.3: perhaps a multiple inheritance line?
  3251.          ((looking-at c-inher-key)
  3252.           (c-add-syntax 'inher-cont-1 (c-point 'boi)))
  3253.          ;; CASE 5D.4: perhaps a template list continuation?
  3254.          ((save-excursion
  3255.         (skip-chars-backward "^<" lim)
  3256.         (= (preceding-char) ?<))
  3257.           ;; we can probably indent it just like and arglist-cont
  3258.           (c-add-syntax 'arglist-cont (point)))
  3259.          ;; CASE 5D.5: perhaps a top-level statement-cont
  3260.          (t
  3261.           (c-beginning-of-statement nil lim)
  3262.           (c-add-syntax 'statement-cont (c-point 'boi)))
  3263.          ))
  3264.        ;; CASE 5E: we are looking at a access specifier
  3265.        ((and inclass-p
  3266.          c-access-key
  3267.          (looking-at c-access-key))
  3268.         (c-add-syntax 'access-label (c-point 'bonl))
  3269.         (c-add-syntax 'inclass (aref inclass-p 0)))
  3270.        ;; CASE 5F: we are looking at the brace which closes the
  3271.        ;; enclosing nested class decl
  3272.        ((and inclass-p
  3273.          (= char-after-ip ?})
  3274.          (save-excursion
  3275.            (save-restriction
  3276.              (widen)
  3277.              (forward-char 1)
  3278.              (and
  3279.               (condition-case nil
  3280.               (progn (backward-sexp 1) t)
  3281.             (error nil))
  3282.               (= (point) (aref inclass-p 1))
  3283.               ))))
  3284.         (save-restriction
  3285.           (widen)
  3286.           (goto-char (aref inclass-p 0))
  3287.           (c-add-syntax 'class-close (c-point 'boi))))
  3288.        ;; CASE 5G: we could be looking at subsequent knr-argdecls
  3289.        ((and c-recognize-knr-p
  3290.          (save-excursion
  3291.            (c-backward-syntactic-ws lim)
  3292.            (while (memq (preceding-char) '(?\; ?,))
  3293.              (beginning-of-line)
  3294.              (setq placeholder (point))
  3295.              (c-backward-syntactic-ws lim))
  3296.            (and (= (preceding-char) ?\))
  3297.             (or (not (eq major-mode 'objc-mode))
  3298.                 (progn
  3299.                   (forward-sexp -1)
  3300.                   (backward-char)
  3301.                   (c-backward-syntactic-ws)
  3302.                   (not (or (= (preceding-char) ?-)
  3303.                        (= (preceding-char) ?+)
  3304.                        ;; or a class category
  3305.                        (progn
  3306.                      (forward-sexp -2)
  3307.                      (looking-at c-class-key))
  3308.                        )))))
  3309.            )
  3310.          (save-excursion
  3311.            (c-beginning-of-statement)
  3312.            (not (looking-at "typedef[ \t\n]+"))))
  3313.         (goto-char placeholder)
  3314.         (c-add-syntax 'knr-argdecl (c-point 'boi)))
  3315.        ;; CASE 5H: we are at the topmost level, make sure we skip
  3316.        ;; back past any access specifiers
  3317.        ((progn
  3318.           (c-backward-syntactic-ws lim)
  3319.           (while (and inclass-p
  3320.               c-access-key
  3321.               (= (preceding-char) ?:)
  3322.               (not (and (eq major-mode 'objc-mode)
  3323.                     (bobp)))
  3324.               (save-excursion
  3325.                 (backward-sexp 1)
  3326.                 (looking-at c-access-key)))
  3327.         (backward-sexp 1)
  3328.         (c-backward-syntactic-ws lim))
  3329.           (or (bobp)
  3330.           (memq (preceding-char) '(?\; ?\}))))
  3331.         (c-add-syntax 'topmost-intro (c-point 'bol))
  3332.         (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3333.        ;; CASE 5I: we are at a method definition continuation line
  3334.        ((and (eq major-mode 'objc-mode)
  3335.          (progn
  3336.            (c-beginning-of-statement 1 lim)
  3337.            (beginning-of-line)
  3338.            (looking-at c-ObjC-method-key)))
  3339.         (c-add-syntax 'objc-method-args-cont (point)))
  3340.        ;; CASE 5J: we are at a topmost continuation line
  3341.        (t
  3342.         (c-beginning-of-statement 1 lim)
  3343.         (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
  3344.        ))                ; end CASE 5
  3345.      ;; CASE 6: line is an expression, not a statement.  Most
  3346.      ;; likely we are either in a function prototype or a function
  3347.      ;; call argument list
  3348.      ((/= (char-after containing-sexp) ?{)
  3349.       (c-backward-syntactic-ws containing-sexp)
  3350.       (cond
  3351.        ;; CASE 6A: we are looking at the arglist closing paren
  3352.        ((and (/= char-before-ip ?,)
  3353.          (memq char-after-ip '(?\) ?\])))
  3354.         (goto-char containing-sexp)
  3355.         (c-add-syntax 'arglist-close (c-point 'boi)))
  3356.        ;; CASE 6B: we are looking at the first argument in an empty
  3357.        ;; argument list. Use arglist-close if we're actually
  3358.        ;; looking at a close paren or bracket.
  3359.        ((memq char-before-ip '(?\( ?\[))
  3360.         (goto-char containing-sexp)
  3361.         (c-add-syntax 'arglist-intro (c-point 'boi)))
  3362.        ;; CASE 6C: we are inside a conditional test clause. treat
  3363.        ;; these things as statements
  3364.        ((save-excursion
  3365.          (goto-char containing-sexp)
  3366.          (and (c-safe (progn (forward-sexp -1) t))
  3367.           (looking-at "\\<for\\>")))
  3368.         (c-beginning-of-statement 1 containing-sexp)
  3369.         (if (= char-before-ip ?\;)
  3370.         (c-add-syntax 'statement (point))
  3371.           (c-add-syntax 'statement-cont (point))
  3372.           ))
  3373.        ;; CASE 6D: maybe a continued method call. This is the case
  3374.        ;; when we are inside a [] bracketed exp, and what precede
  3375.        ;; the opening bracket is not an identifier.
  3376.        ((and (eq major-mode 'objc-mode)
  3377.          (= (char-after containing-sexp) ?\[)
  3378.          (save-excursion
  3379.            (goto-char (1- containing-sexp))
  3380.            (c-backward-syntactic-ws (c-point 'bod))
  3381.            (if (not (looking-at c-symbol-key))
  3382.                (c-add-syntax 'objc-method-call-cont containing-sexp))
  3383.            )))
  3384.        ;; CASE 6E: we are looking at an arglist continuation line,
  3385.        ;; but the preceding argument is on the same line as the
  3386.        ;; opening paren.  This case includes multi-line
  3387.        ;; mathematical paren groupings, but we could be on a
  3388.        ;; for-list continuation line
  3389.        ((and (save-excursion
  3390.            (goto-char (1+ containing-sexp))
  3391.            (skip-chars-forward " \t")
  3392.            (not (eolp)))
  3393.          (save-excursion
  3394.            (c-beginning-of-statement)
  3395.            (skip-chars-backward " \t([")
  3396.            (<= (point) containing-sexp)))
  3397.         (goto-char containing-sexp)
  3398.         (c-add-syntax 'arglist-cont-nonempty (c-point 'boi)))
  3399.        ;; CASE 6F: we are looking at just a normal arglist
  3400.        ;; continuation line
  3401.        (t (c-beginning-of-statement 1 containing-sexp)
  3402.           (forward-char 1)
  3403.           (c-forward-syntactic-ws indent-point)
  3404.           (c-add-syntax 'arglist-cont (c-point 'boi)))
  3405.        ))
  3406.      ;; CASE 7: func-local multi-inheritance line
  3407.      ((save-excursion
  3408.         (goto-char indent-point)
  3409.         (skip-chars-forward " \t")
  3410.         (looking-at c-baseclass-key))
  3411.       (goto-char indent-point)
  3412.       (skip-chars-forward " \t")
  3413.       (cond
  3414.        ;; CASE 7A: non-hanging colon on an inher intro
  3415.        ((= char-after-ip ?:)
  3416.         (c-backward-syntactic-ws lim)
  3417.         (c-add-syntax 'inher-intro (c-point 'boi)))
  3418.        ;; CASE 7B: hanging colon on an inher intro
  3419.        ((= char-before-ip ?:)
  3420.         (c-add-syntax 'inher-intro (c-point 'boi)))
  3421.        ;; CASE 7C: a continued inheritance line
  3422.        (t
  3423.         (c-beginning-of-inheritance-list lim)
  3424.         (c-add-syntax 'inher-cont (point))
  3425.         )))
  3426.      ;; CASE 8: we are inside a brace-list
  3427.      ((setq placeholder (c-inside-bracelist-p containing-sexp state))
  3428.       (cond
  3429.        ;; CASE 8A: brace-list-close brace
  3430.        ((and (= char-after-ip ?})
  3431.          (c-safe (progn (forward-char 1)
  3432.                 (backward-sexp 1)
  3433.                 t))
  3434.          (= (point) containing-sexp))
  3435.         (c-add-syntax 'brace-list-close (c-point 'boi)))
  3436.        ;; CASE 8B: we're looking at the first line in a brace-list
  3437.        ((save-excursion
  3438.           (goto-char indent-point)
  3439.           (c-backward-syntactic-ws containing-sexp)
  3440.           (= (point) (1+ containing-sexp)))
  3441.         (goto-char containing-sexp)
  3442.         ;;(if (= char-after-ip ?{)
  3443.         ;;(c-add-syntax 'brace-list-open (c-point 'boi))
  3444.         (c-add-syntax 'brace-list-intro (c-point 'boi))
  3445.         )
  3446.         ;;))            ; end CASE 8B
  3447.        ;; CASE 8C: this is just a later brace-list-entry
  3448.        (t (goto-char (1+ containing-sexp))
  3449.           (c-forward-syntactic-ws indent-point)
  3450.           (if (= char-after-ip ?{)
  3451.           (c-add-syntax 'brace-list-open (point))
  3452.         (c-add-syntax 'brace-list-entry (point))
  3453.         ))            ; end CASE 8C
  3454.        ))                ; end CASE 8
  3455.      ;; CASE 9: A continued statement
  3456.      ((and (not (memq char-before-ip '(?\; ?} ?:)))
  3457.            (> (point)
  3458.           (save-excursion
  3459.             (c-beginning-of-statement 1 containing-sexp)
  3460.             (setq placeholder (point))))
  3461.            (/= placeholder containing-sexp))
  3462.       (goto-char indent-point)
  3463.       (skip-chars-forward " \t")
  3464.       (let ((after-cond-placeholder
  3465.          (save-excursion
  3466.            (goto-char placeholder)
  3467.            (if (looking-at c-conditional-key)
  3468.                (progn
  3469.              (c-safe (c-skip-conditional))
  3470.              (c-forward-syntactic-ws)
  3471.              (if (memq (following-char) '(?\;))
  3472.                  (progn
  3473.                    (forward-char 1)
  3474.                    (c-forward-syntactic-ws)))
  3475.              (point))
  3476.              nil))))
  3477.         (cond
  3478.          ;; CASE 9A: substatement
  3479.          ((and after-cond-placeholder
  3480.            (>= after-cond-placeholder indent-point))
  3481.           (goto-char placeholder)
  3482.           (if (= char-after-ip ?{)
  3483.           (c-add-syntax 'substatement-open (c-point 'boi))
  3484.         (c-add-syntax 'substatement (c-point 'boi))))
  3485.          ;; CASE 9B: open braces for class or brace-lists
  3486.          ((= char-after-ip ?{)
  3487.           (cond
  3488.            ;; CASE 9B.1: class-open
  3489.            ((save-excursion
  3490.           (goto-char indent-point)
  3491.           (skip-chars-forward " \t{")
  3492.           (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  3493.             (and decl
  3494.              (setq placeholder (aref decl 0)))
  3495.             ))
  3496.         (c-add-syntax 'class-open placeholder))
  3497.            ;; CASE 9B.2: brace-list-open
  3498.            ((or (save-excursion
  3499.               (goto-char placeholder)
  3500.               (looking-at "\\<enum\\>"))
  3501.             (= char-before-ip ?=))
  3502.         (c-add-syntax 'brace-list-open placeholder))
  3503.            ;; CASE 9B.3: catch-all for unknown construct.
  3504.            (t
  3505.         ;; Even though this isn't right, it's the best I'm
  3506.         ;; going to do for now. Exceptions probably fall
  3507.         ;; through to here, but aren't supported yet.  Also,
  3508.         ;; after the next release, I may call a recognition
  3509.         ;; hook like so: (run-hooks 'c-recognize-hook), but I
  3510.         ;; dunno.
  3511.         (c-add-syntax 'statement-cont placeholder)
  3512.         (c-add-syntax 'block-open))
  3513.            ))
  3514.          ;; CASE 9C: iostream insertion or extraction operator
  3515.          ((looking-at "<<\\|>>")
  3516.           (goto-char placeholder)
  3517.           (and after-cond-placeholder
  3518.            (goto-char after-cond-placeholder))
  3519.           (while (and (re-search-forward "<<\\|>>" indent-point 'move)
  3520.               (c-in-literal placeholder)))
  3521.           ;; if we ended up at indent-point, then the first
  3522.           ;; streamop is on a separate line. Indent the line like
  3523.           ;; a statement-cont instead
  3524.           (if (/= (point) indent-point)
  3525.           (c-add-syntax 'stream-op (c-point 'boi))
  3526.         (c-backward-syntactic-ws lim)
  3527.         (c-add-syntax 'statement-cont (c-point 'boi))))
  3528.          ;; CASE 9D: continued statement. find the accurate
  3529.          ;; beginning of statement or substatement
  3530.          (t
  3531.           (c-beginning-of-statement nil after-cond-placeholder)
  3532.           (c-add-syntax 'statement-cont (point)))
  3533.          )))
  3534.      ;; CASE 10: an else clause?
  3535.      ((looking-at "\\<else\\>")
  3536.       (c-backward-to-start-of-if containing-sexp)
  3537.       (c-add-syntax 'else-clause (c-point 'boi)))
  3538.      ;; CASE 11: Statement. But what kind?  Lets see if its a
  3539.      ;; while closure of a do/while construct
  3540.      ((progn
  3541.         (goto-char indent-point)
  3542.         (skip-chars-forward " \t")
  3543.         (and (looking-at "while\\b[^_]")
  3544.          (save-excursion
  3545.            (c-backward-to-start-of-do containing-sexp)
  3546.            (setq placeholder (point))
  3547.            (looking-at "do\\b[^_]"))
  3548.          ))
  3549.       (c-add-syntax 'do-while-closure placeholder))
  3550.      ;; CASE 12: A case or default label
  3551.      ((looking-at c-switch-label-key)
  3552.       (goto-char containing-sexp)
  3553.       ;; for a case label, we set relpos the first non-whitespace
  3554.       ;; char on the line containing the switch opening brace. this
  3555.       ;; should handle hanging switch opening braces correctly.
  3556.       (c-add-syntax 'case-label (c-point 'boi)))
  3557.      ;; CASE 13: any other label
  3558.      ((looking-at c-label-key)
  3559.       (goto-char containing-sexp)
  3560.       (c-add-syntax 'label (c-point 'boi)))
  3561.      ;; CASE 14: block close brace, possibly closing the defun or
  3562.      ;; the class
  3563.      ((= char-after-ip ?})
  3564.       (let ((relpos (save-excursion
  3565.               (goto-char containing-sexp)
  3566.               (if (/= (point) (c-point 'boi))
  3567.                   (c-beginning-of-statement))
  3568.               (c-point 'boi))))
  3569.         (cond
  3570.          ;; CASE 14A: does this close an inline?
  3571.          ((progn
  3572.         (goto-char containing-sexp)
  3573.         (c-search-uplist-for-classkey state))
  3574.           (c-add-syntax 'inline-close relpos))
  3575.          ;; CASE 14B: if there an enclosing brace that hasn't
  3576.          ;; been narrowed out by a class, then this is a
  3577.          ;; block-close
  3578.          ((c-most-enclosing-brace state)
  3579.           (c-add-syntax 'block-close relpos))
  3580.          ;; CASE 14C: find out whether we're closing a top-level
  3581.          ;; class or a defun
  3582.          (t
  3583.           (save-restriction
  3584.         (narrow-to-region (point-min) indent-point)
  3585.         (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  3586.           (if decl
  3587.               (c-add-syntax 'class-close (aref decl 0))
  3588.             (c-add-syntax 'defun-close relpos)))))
  3589.          )))
  3590.      ;; CASE 15: statement catchall
  3591.      (t
  3592.       ;; we know its a statement, but we need to find out if it is
  3593.       ;; the first statement in a block
  3594.       (goto-char containing-sexp)
  3595.       (forward-char 1)
  3596.       (c-forward-syntactic-ws indent-point)
  3597.       ;; we want to ignore labels when skipping forward
  3598.       (let ((ignore-re (concat c-switch-label-key "\\|" c-label-key))
  3599.         inswitch-p)
  3600.         (while (looking-at ignore-re)
  3601.           (if (looking-at c-switch-label-key)
  3602.           (progn
  3603.             (setq inswitch-p t)
  3604.             ;; we also want to skip over the body of the
  3605.             ;; case/switch statement if that doesn't put us at
  3606.             ;; after the indent-point
  3607.             (while (c-skip-case-statement-forward indent-point))))
  3608.           (forward-line 1)
  3609.           (c-forward-syntactic-ws indent-point))
  3610.         (cond
  3611.          ;; CASE 15A: we saw a case/default statement so we must be
  3612.          ;; in a switch statement.  find out if we are at the
  3613.          ;; statement just after a case or default label
  3614.          ((and inswitch-p
  3615.            (save-excursion
  3616.              (goto-char indent-point)
  3617.              (c-backward-syntactic-ws containing-sexp)
  3618.              (back-to-indentation)
  3619.              (setq placeholder (point))
  3620.              (looking-at c-switch-label-key)))
  3621.           (goto-char indent-point)
  3622.           (skip-chars-forward " \t")
  3623.           (if (= (following-char) ?{)
  3624.           (c-add-syntax 'statement-case-open placeholder)
  3625.         (c-add-syntax 'statement-case-intro placeholder)))
  3626.          ;; CASE 15B: continued statement
  3627.          ((= char-before-ip ?,)
  3628.           (c-add-syntax 'statement-cont (c-point 'boi)))
  3629.          ;; CASE 15C: a question/colon construct?  But make sure
  3630.          ;; what came before was not a label, and what comes after
  3631.          ;; is not a globally scoped function call!
  3632.          ((or (and (memq char-before-ip '(?: ??))
  3633.                (save-excursion
  3634.              (goto-char indent-point)
  3635.              (c-backward-syntactic-ws lim)
  3636.              (back-to-indentation)
  3637.              (not (looking-at c-label-key))))
  3638.           (and (memq char-after-ip '(?: ??))
  3639.                (save-excursion
  3640.              (goto-char indent-point)
  3641.              (skip-chars-forward " \t")
  3642.              ;; watch out for scope operator
  3643.              (not (looking-at "::")))))
  3644.           (c-add-syntax 'statement-cont (c-point 'boi)))
  3645.          ;; CASE 15D: any old statement
  3646.          ((< (point) indent-point)
  3647.           (c-add-syntax 'statement (c-point 'boi))
  3648.           (if (= char-after-ip ?{)
  3649.           (c-add-syntax 'block-open)))
  3650.          ;; CASE 15E: first statement in an inline, or first
  3651.          ;; statement in a top-level defun. we can tell this is it
  3652.          ;; if there are no enclosing braces that haven't been
  3653.          ;; narrowed out by a class (i.e. don't use bod here!)
  3654.          ((save-excursion
  3655.         (save-restriction
  3656.           (widen)
  3657.           (goto-char containing-sexp)
  3658.           (c-narrow-out-enclosing-class state containing-sexp)
  3659.           (not (c-most-enclosing-brace state))))
  3660.           (goto-char containing-sexp)
  3661.           ;; if not at boi, then defun-opening braces are hung on
  3662.           ;; right side, so we need a different relpos
  3663.           (if (/= (point) (c-point 'boi))
  3664.           (progn
  3665.             (c-backward-syntactic-ws)
  3666.             (c-safe (forward-sexp (if (= (preceding-char) ?\))
  3667.                           -1 -2)))
  3668.             ))
  3669.           (c-add-syntax 'defun-block-intro (c-point 'boi)))
  3670.          ;; CASE 15F: first statement in a block
  3671.          (t (goto-char containing-sexp)
  3672.         (if (/= (point) (c-point 'boi))
  3673.             (c-beginning-of-statement))
  3674.         (c-add-syntax 'statement-block-intro (c-point 'boi))
  3675.         (if (= char-after-ip ?{)
  3676.             (c-add-syntax 'block-open)))
  3677.          )))
  3678.      )
  3679.  
  3680.     ;; now we need to look at any modifiers
  3681.     (goto-char indent-point)
  3682.     (skip-chars-forward " \t")
  3683.     (if (looking-at c-comment-start-regexp)
  3684.         ;; we are looking at a comment. if the comment is at or to
  3685.         ;; the right of comment-column, then all we want on the
  3686.         ;; syntax list is comment-intro, otherwise, the
  3687.         ;; indentation of the comment is relative to where a
  3688.         ;; normal statement would indent
  3689.         (if (< (current-column) comment-column)
  3690.         (c-add-syntax 'comment-intro)
  3691.           ;; reset syntax kludge
  3692.           (setq syntax nil)
  3693.           (c-add-syntax 'comment-intro)))
  3694.     ;; we might want to give additional offset to friends (in C++)
  3695.     (if (and (eq major-mode 'c++-mode)
  3696.          (looking-at "friend[ \t]+"))
  3697.         (c-add-syntax 'friend))
  3698.     ;; return the syntax
  3699.     syntax))))
  3700.  
  3701.  
  3702. ;; indent via syntactic language elements
  3703. (defun c-get-offset (langelem)
  3704.   ;; Get offset from LANGELEM which is a cons cell of the form:
  3705.   ;; (SYMBOL . RELPOS).  The symbol is matched against
  3706.   ;; c-offsets-alist and the offset found there is either returned,
  3707.   ;; or added to the indentation at RELPOS.  If RELPOS is nil, then
  3708.   ;; the offset is simply returned.
  3709.   (let* ((symbol (car langelem))
  3710.      (relpos (cdr langelem))
  3711.      (match  (assq symbol c-offsets-alist))
  3712.      (offset (cdr-safe match)))
  3713.     ;; offset can be a number, a function, a variable, or one of the
  3714.     ;; symbols + or -
  3715.     (cond
  3716.      ((not match)
  3717.       (if c-strict-syntax-p
  3718.       (error "don't know how to indent a %s" symbol)
  3719.     (setq offset 0
  3720.           relpos 0)))
  3721.      ((eq offset '+)  (setq offset c-basic-offset))
  3722.      ((eq offset '-)  (setq offset (- c-basic-offset)))
  3723.      ((eq offset '++) (setq offset (* 2 c-basic-offset)))
  3724.      ((eq offset '--) (setq offset (* 2 (- c-basic-offset))))
  3725.      ((and (not (numberp offset))
  3726.        (fboundp offset))
  3727.       (setq offset (funcall offset langelem)))
  3728.      ((not (numberp offset))
  3729.       (setq offset (eval offset)))
  3730.      )
  3731.     (+ (if (and relpos
  3732.         (< relpos (c-point 'bol)))
  3733.        (save-excursion
  3734.          (goto-char relpos)
  3735.          (current-column))
  3736.      0)
  3737.        offset)))
  3738.  
  3739. (defun c-indent-line (&optional syntax)
  3740.   ;; indent the current line as C/C++/ObjC code. Optional SYNTAX is the
  3741.   ;; syntactic information for the current line. Returns the amount of
  3742.   ;; indentation change
  3743.   (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax)))
  3744.      (pos (- (point-max) (point)))
  3745.      (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context)))
  3746.      (shift-amt  (- (current-indentation) indent)))
  3747.     (and c-echo-syntactic-information-p
  3748.      (message "syntax: %s, indent= %d" c-syntactic-context indent))
  3749.     (if (zerop shift-amt)
  3750.     nil
  3751.       (delete-region (c-point 'bol) (c-point 'boi))
  3752.       (beginning-of-line)
  3753.       (indent-to indent))
  3754.     (if (< (point) (c-point 'boi))
  3755.     (back-to-indentation)
  3756.       ;; If initial point was within line's indentation, position after
  3757.       ;; the indentation.  Else stay at same point in text.
  3758.       (if (> (- (point-max) pos) (point))
  3759.       (goto-char (- (point-max) pos)))
  3760.       )
  3761.     (run-hooks 'c-special-indent-hook)
  3762.     shift-amt))
  3763.  
  3764. (defun c-show-syntactic-information ()
  3765.   "Show syntactic information for current line."
  3766.   (interactive)
  3767.   (message "syntactic analysis: %s" (c-guess-basic-syntax))
  3768.   (c-keep-region-active))
  3769.  
  3770.  
  3771. ;; Standard indentation line-ups
  3772. (defun c-lineup-arglist (langelem)
  3773.   ;; lineup the current arglist line with the arglist appearing just
  3774.   ;; after the containing paren which starts the arglist.
  3775.   (save-excursion
  3776.     (let* ((containing-sexp
  3777.         (save-excursion
  3778.           ;; arglist-cont-nonempty gives relpos ==
  3779.           ;; to boi of containing-sexp paren. This
  3780.           ;; is good when offset is +, but bad
  3781.           ;; when it is c-lineup-arglist, so we
  3782.           ;; have to special case a kludge here.
  3783.           (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
  3784.           (progn
  3785.             (beginning-of-line)
  3786.             (backward-up-list 1)
  3787.             (skip-chars-forward " \t" (c-point 'eol)))
  3788.         (goto-char (cdr langelem)))
  3789.           (point)))
  3790.        (cs-curcol (save-excursion
  3791.             (goto-char (cdr langelem))
  3792.             (current-column))))
  3793.       (if (save-excursion
  3794.         (beginning-of-line)
  3795.         (looking-at "[ \t]*)"))
  3796.       (progn (goto-char (match-end 0))
  3797.          (forward-sexp -1)
  3798.          (forward-char 1)
  3799.          (c-forward-syntactic-ws)
  3800.          (- (current-column) cs-curcol))
  3801.     (goto-char containing-sexp)
  3802.     (or (eolp)
  3803.         (let ((eol (c-point 'eol))
  3804.           (here (progn
  3805.               (forward-char 1)
  3806.               (skip-chars-forward " \t")
  3807.               (point))))
  3808.           (c-forward-syntactic-ws)
  3809.           (if (< (point) eol)
  3810.           (goto-char here))))
  3811.     (- (current-column) cs-curcol)
  3812.     ))))
  3813.  
  3814. (defun c-lineup-arglist-intro-after-paren (langelem)
  3815.   ;; lineup an arglist-intro line to just after the open paren
  3816.   (save-excursion
  3817.     (let ((cs-curcol (save-excursion
  3818.                (goto-char (cdr langelem))
  3819.                (current-column)))
  3820.       (ce-curcol (save-excursion
  3821.                (beginning-of-line)
  3822.                (backward-up-list 1)
  3823.                (skip-chars-forward " \t" (c-point 'eol))
  3824.                (current-column))))
  3825.       (- ce-curcol cs-curcol -1))))
  3826.  
  3827. (defun c-lineup-streamop (langelem)
  3828.   ;; lineup stream operators
  3829.   (save-excursion
  3830.     (let* ((relpos (cdr langelem))
  3831.        (curcol (progn (goto-char relpos)
  3832.               (current-column))))
  3833.       (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
  3834.       (goto-char (match-beginning 0))
  3835.       (- (current-column) curcol))))
  3836.  
  3837. (defun c-lineup-multi-inher (langelem)
  3838.   ;; line up multiple inheritance lines
  3839.   (save-excursion
  3840.     (let (cs-curcol
  3841.       (eol (c-point 'eol))
  3842.       (here (point)))
  3843.       (goto-char (cdr langelem))
  3844.       (setq cs-curcol (current-column))
  3845.       (skip-chars-forward "^:" eol)
  3846.       (skip-chars-forward " \t:" eol)
  3847.       (if (or (eolp)
  3848.           (looking-at c-comment-start-regexp))
  3849.       (c-forward-syntactic-ws here))
  3850.       (- (current-column) cs-curcol)
  3851.       )))
  3852.  
  3853. (defun c-lineup-C-comments (langelem)
  3854.   ;; line up C block comment continuation lines
  3855.   (save-excursion
  3856.     (let ((stars (progn
  3857.            (beginning-of-line)
  3858.            (skip-chars-forward " \t")
  3859.            (if (looking-at "\\*\\*?")
  3860.                (- (match-end 0) (match-beginning 0))
  3861.              0)))
  3862.       (cs-curcol (progn (goto-char (cdr langelem))
  3863.                 (current-column))))
  3864.       (back-to-indentation)
  3865.       (if (re-search-forward "/\\*[ \t]*" (c-point 'eol) t)
  3866.       (goto-char (+ (match-beginning 0)
  3867.             (cond
  3868.              (c-block-comments-indent-p 0)
  3869.              ((= stars 1) 1)
  3870.              ((= stars 2) 0)
  3871.              (t (- (match-end 0) (match-beginning 0)))))))
  3872.       (- (current-column) cs-curcol))))
  3873.  
  3874. (defun c-lineup-comment (langelem)
  3875.   ;; support old behavior for comment indentation. we look at
  3876.   ;; c-comment-only-line-offset to decide how to indent comment
  3877.   ;; only-lines
  3878.   (save-excursion
  3879.     (back-to-indentation)
  3880.     ;; at or to the right of comment-column
  3881.     (if (>= (current-column) comment-column)
  3882.     (c-comment-indent)
  3883.       ;; otherwise, indent as specified by c-comment-only-line-offset
  3884.       (if (not (bolp))
  3885.       (or (car-safe c-comment-only-line-offset)
  3886.           c-comment-only-line-offset)
  3887.     (or (cdr-safe c-comment-only-line-offset)
  3888.         (car-safe c-comment-only-line-offset)
  3889.         -1000            ;jam it against the left side
  3890.         )))))
  3891.  
  3892. (defun c-lineup-runin-statements (langelem)
  3893.   ;; line up statements in coding standards which place the first
  3894.   ;; statement on the same line as the block opening brace.
  3895.   (if (= (char-after (cdr langelem)) ?{)
  3896.       (save-excursion
  3897.     (let ((curcol (progn
  3898.             (goto-char (cdr langelem))
  3899.             (current-column))))
  3900.       (forward-char 1)
  3901.       (skip-chars-forward " \t")
  3902.       (- (current-column) curcol)))
  3903.     0))
  3904.  
  3905. (defun c-lineup-math (langelem)
  3906.   ;; line up math statement-cont after the equals
  3907.   (save-excursion
  3908.     (let* ((relpos (cdr langelem))
  3909.        (equalp (save-excursion
  3910.              (goto-char (c-point 'boi))
  3911.              (skip-chars-forward "^=" (c-point 'eol))
  3912.              (and (= (following-char) ?=)
  3913.               (- (point) (c-point 'boi)))))
  3914.        (curcol (progn
  3915.              (goto-char relpos)
  3916.              (current-column)))
  3917.        donep)
  3918.       (while (and (not donep)
  3919.           (< (point) (c-point 'eol)))
  3920.     (skip-chars-forward "^=" (c-point 'eol))
  3921.     (if (c-in-literal (cdr langelem))
  3922.         (forward-char 1)
  3923.       (setq donep t)))
  3924.       (if (/= (following-char) ?=)
  3925.       ;; there's no equal sign on the line
  3926.       c-basic-offset
  3927.     ;; calculate indentation column after equals and ws, unless
  3928.     ;; our line contains an equals sign
  3929.     (if (not equalp)
  3930.         (progn
  3931.           (forward-char 1)
  3932.           (skip-chars-forward " \t")
  3933.           (setq equalp 0)))
  3934.     (- (current-column) equalp curcol))
  3935.       )))
  3936.  
  3937. (defun c-lineup-objc-method-call (langelem)
  3938.   ;; Line up methods args as elisp-mode does with function args
  3939.   (save-excursion
  3940.     (let* ((relpos (cdr langelem))
  3941.        (curcol (progn (goto-char relpos)
  3942.               (current-column))))
  3943.       ;; We are now on the opening square bracket
  3944.       (forward-char)           
  3945.       (forward-sexp)
  3946.       (- (1+ (current-column)) curcol))))
  3947.  
  3948. (defun c-lineup-objc-method-args (langelem)
  3949.   ;; Line up the colons that separate args. This is done trying to
  3950.   ;; align colons vertically.
  3951.   (save-excursion
  3952.     (let* ((here (c-point 'boi))
  3953.        (curcol (progn (goto-char here) (current-column)))
  3954.        (eol (c-point 'eol))
  3955.        (relpos (cdr langelem))
  3956.        (first-col-column (progn
  3957.                    (goto-char relpos)
  3958.                    (skip-chars-forward "^:" eol)
  3959.                    (and (= (following-char) ?:)
  3960.                     (current-column)))))
  3961.       (if (not first-col-column)
  3962.       c-basic-offset
  3963.     (goto-char here)
  3964.     (skip-chars-forward "^:" eol)
  3965.     (if (= (following-char) ?:)
  3966.         (+ curcol (- first-col-column (current-column)))
  3967.       c-basic-offset)))))
  3968.  
  3969. (defun c-lineup-objc-method-args-2 (langelem)
  3970.   ;; Line up the colons that separate args. This is done trying to
  3971.   ;; align the colon on the current line with the previous one.
  3972.   (save-excursion
  3973.     (let* ((here (c-point 'boi))
  3974.        (curcol (progn (goto-char here) (current-column)))
  3975.        (eol (c-point 'eol))
  3976.        (relpos (cdr langelem))
  3977.        (prev-col-column (progn
  3978.                   (skip-chars-backward "^:" relpos)
  3979.                   (and (= (preceding-char) ?:)
  3980.                    (- (current-column) 1)))))
  3981.       (if (not prev-col-column)
  3982.       c-basic-offset
  3983.     (goto-char here)
  3984.     (skip-chars-forward "^:" eol)
  3985.     (if (= (following-char) ?:)
  3986.         (+ curcol (- prev-col-column (current-column)))
  3987.       c-basic-offset)))))
  3988.  
  3989.  
  3990. ;; commands for "macroizations" -- making C++ parameterized types via
  3991. ;; macros. Also commands for commentifying regions
  3992.  
  3993. (defun c-backslashify-current-line (doit)
  3994.   ;; Backslashifies current line if DOIT is non-nil, otherwise
  3995.   ;; unbackslashifies the current line.
  3996.   (end-of-line)
  3997.   (if doit
  3998.       ;; Note that "\\\\" is needed to get one backslash.
  3999.       (if (not (save-excursion
  4000.          (forward-char -1)
  4001.          (looking-at "\\\\")))
  4002.       (progn
  4003.         (if (>= (current-column) c-backslash-column)
  4004.         (insert " \\")
  4005.           (while (<= (current-column) c-backslash-column)
  4006.         (insert "\t")
  4007.         (end-of-line))
  4008.           (delete-char -1)
  4009.           (while (< (current-column) c-backslash-column)
  4010.         (insert " ")
  4011.         (end-of-line))
  4012.           (insert "\\"))))
  4013.     (if (not (bolp))
  4014.     (progn
  4015.       (forward-char -1)
  4016.       (if (looking-at "\\\\")
  4017.           (progn
  4018.         (skip-chars-backward " \t")
  4019.         (delete-region (point) (c-point 'eol))))
  4020.       ))))
  4021.  
  4022. (defun c-backslash-region (beg end arg)
  4023.   "Insert backslashes at end of every line in region.
  4024. Useful for defining cpp macros.  If called with a prefix argument,
  4025. it trailing backslashes are removed."
  4026.   (interactive "r\nP")
  4027.   (save-excursion
  4028.     (let ((do-lastline-p (progn (goto-char end) (not (bolp)))))
  4029.       (save-restriction
  4030.     (narrow-to-region beg end)
  4031.     (goto-char (point-min))
  4032.     (while (not (save-excursion
  4033.               (forward-line 1)
  4034.               (eobp)))
  4035.       (c-backslashify-current-line (null arg))
  4036.       (forward-line 1)))
  4037.       (and do-lastline-p
  4038.        (progn (goto-char end)
  4039.           (c-backslashify-current-line (null arg))))
  4040.       )))
  4041.  
  4042. ;;(defun comment-region (beg end &optional arg)
  4043. ;;  "Comment or uncomment each line in the region.
  4044. ;;With just C-u prefix arg, uncomment each line in region.
  4045. ;;Numeric prefix arg ARG means use ARG comment characters.
  4046. ;;If ARG is negative, delete that many comment characters instead.
  4047. ;;Comments are terminated on each line, even for syntax in which newline does
  4048. ;;not end the comment.  Blank lines do not get comments."
  4049. ;;  ;; if someone wants it to only put a comment-start at the beginning and
  4050. ;;  ;; comment-end at the end then typing it, C-x C-x, closing it, C-x C-x
  4051. ;;  ;; is easy enough.  No option is made here for other than commenting
  4052. ;;  ;; every line.
  4053. ;;  (interactive "r\nP")
  4054. ;;  (or comment-start (error "No comment syntax is defined"))
  4055. ;;  (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
  4056. ;;  (save-excursion
  4057. ;;    (save-restriction
  4058. ;;      (let ((cs comment-start) (ce comment-end)
  4059. ;;        numarg)
  4060. ;;        (if (consp arg) (setq numarg t)
  4061. ;;      (setq numarg (prefix-numeric-value arg))
  4062. ;;      ;; For positive arg > 1, replicate the comment delims now,
  4063. ;;      ;; then insert the replicated strings just once.
  4064. ;;      (while (> numarg 1)
  4065. ;;        (setq cs (concat cs comment-start)
  4066. ;;          ce (concat ce comment-end))
  4067. ;;        (setq numarg (1- numarg))))
  4068. ;;    ;; Loop over all lines from BEG to END.
  4069. ;;        (narrow-to-region beg end)
  4070. ;;        (goto-char beg)
  4071. ;;        (while (not (eobp))
  4072. ;;          (if (or (eq numarg t) (< numarg 0))
  4073. ;;          (progn
  4074. ;;        ;; Delete comment start from beginning of line.
  4075. ;;        (if (eq numarg t)
  4076. ;;            (while (looking-at (regexp-quote cs))
  4077. ;;              (delete-char (length cs)))
  4078. ;;          (let ((count numarg))
  4079. ;;            (while (and (> 1 (setq count (1+ count)))
  4080. ;;                (looking-at (regexp-quote cs)))
  4081. ;;              (delete-char (length cs)))))
  4082. ;;        ;; Delete comment end from end of line.
  4083. ;;                (if (string= "" ce)
  4084. ;;            nil
  4085. ;;          (if (eq numarg t)
  4086. ;;              (progn
  4087. ;;            (end-of-line)
  4088. ;;            ;; This is questionable if comment-end ends in
  4089. ;;            ;; whitespace.  That is pretty brain-damaged,
  4090. ;;            ;; though.
  4091. ;;            (skip-chars-backward " \t")
  4092. ;;            (if (and (>= (- (point) (point-min)) (length ce))
  4093. ;;                 (save-excursion
  4094. ;;                   (backward-char (length ce))
  4095. ;;                   (looking-at (regexp-quote ce))))
  4096. ;;                (delete-char (- (length ce)))))
  4097. ;;            (setq count numarg)
  4098. ;;            (while (> 1 (setq count (1+ count)))
  4099. ;;              (end-of-line)
  4100. ;;              ;; this is questionable if comment-end ends in whitespace
  4101. ;;              ;; that is pretty brain-damaged though
  4102. ;;              (skip-chars-backward " \t")
  4103. ;;              (save-excursion
  4104. ;;            (backward-char (length ce))
  4105. ;;            (if (looking-at (regexp-quote ce))
  4106. ;;                (delete-char (length ce)))))))
  4107. ;;        (forward-line 1))
  4108. ;;        ;; Insert at beginning and at end.
  4109. ;;            (if (looking-at "[ \t]*$") ()
  4110. ;;              (insert cs)
  4111. ;;              (if (string= "" ce) ()
  4112. ;;                (end-of-line)
  4113. ;;                (insert ce)))
  4114. ;;            (search-forward "\n" nil 'move)))))))
  4115.  
  4116.  
  4117. ;; defuns for submitting bug reports
  4118.  
  4119. (defconst c-version "4.85"
  4120.   "cc-mode version number.")
  4121. (defconst c-mode-help-address "cc-mode-help@anthem.nlm.nih.gov"
  4122.   "Address accepting submission of bug reports.")
  4123.  
  4124. (defun c-version ()
  4125.   "Echo the current version of cc-mode in the minibuffer."
  4126.   (interactive)
  4127.   (message "Using cc-mode version %s" c-version)
  4128.   (c-keep-region-active))
  4129.  
  4130. ;; get reporter-submit-bug-report when byte-compiling
  4131. (and (fboundp 'eval-when-compile)
  4132.      (eval-when-compile
  4133.       (require 'reporter)))
  4134.  
  4135. (defun c-submit-bug-report ()
  4136.   "Submit via mail a bug report on cc-mode."
  4137.   (interactive)
  4138.   ;; load in reporter
  4139.   (let ((reporter-prompt-for-summary-p t))
  4140.     (and
  4141.      (y-or-n-p "Do you want to submit a report on cc-mode? ")
  4142.      (require 'reporter)
  4143.      (reporter-submit-bug-report
  4144.       c-mode-help-address
  4145.       (concat "cc-mode " c-version " ("
  4146.           (cond ((eq major-mode 'c++-mode)  "C++")
  4147.             ((eq major-mode 'c-mode)    "C")
  4148.             ((eq major-mode 'objc-mode) "ObjC"))
  4149.           ")")
  4150.       (let ((vars (list
  4151.            ;; report only the vars that affect indentation
  4152.            'c-basic-offset
  4153.            'c-offsets-alist
  4154.            'c-block-comments-indent-p
  4155.            'c-cleanup-list
  4156.            'c-comment-only-line-offset
  4157.            'c-backslash-column
  4158.            'c-delete-function
  4159.            'c-electric-pound-behavior
  4160.            'c-hanging-braces-alist
  4161.            'c-hanging-colons-alist
  4162.            'c-hanging-comment-ender-p
  4163.            'c-tab-always-indent
  4164.            'c-recognize-knr-p
  4165.            'defun-prompt-regexp
  4166.            'tab-width
  4167.            )))
  4168.     (if (not (boundp 'defun-prompt-regexp))
  4169.         (delq 'defun-prompt-regexp vars)
  4170.       vars))
  4171.       (function
  4172.        (lambda ()
  4173.      (insert
  4174.       (if c-special-indent-hook
  4175.           (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  4176.               "c-special-indent-hook is set to '"
  4177.               (format "%s" c-special-indent-hook)
  4178.               ".\nPerhaps this is your problem?\n"
  4179.               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
  4180.         "\n")
  4181.       (format "c-emacs-features: %s\n" c-emacs-features)
  4182.       )))
  4183.       nil
  4184.       "Dear Barry,"
  4185.       ))))
  4186.  
  4187.  
  4188. ;; menus for XEmacs (formerly Lucid)
  4189. (defun c-popup-menu (e)
  4190.   "Pops up the C/C++/ObjC menu."
  4191.   (interactive "@e")
  4192.   (popup-menu (cons (concat mode-name " Mode Commands") c-mode-menu))
  4193.   (c-keep-region-active))
  4194.     
  4195.  
  4196. ;; fsets for compatibility with BOCM
  4197. (fset 'electric-c-brace      'c-electric-brace)
  4198. (fset 'electric-c-semi       'c-electric-semi&comma)
  4199. (fset 'electric-c-sharp-sign 'c-electric-pound)
  4200. ;; there is no cc-mode equivalent for electric-c-terminator
  4201. (fset 'mark-c-function       'c-mark-function)
  4202. (fset 'indent-c-exp          'c-indent-exp)
  4203. (fset 'set-c-style           'c-set-style)
  4204. ;; lemacs 19.9 + font-lock + cc-mode - c++-mode lossage
  4205. (fset 'c++-beginning-of-defun 'beginning-of-defun)
  4206. (fset 'c++-end-of-defun 'end-of-defun)
  4207.  
  4208. ;; set up bc warnings for obsolete variables, but for now lets not
  4209. ;; worry about obsolete functions.  maybe later some will be important
  4210. ;; to flag
  4211. (and (memq 'v19 c-emacs-features)
  4212.      (let* ((na "Nothing appropriate.")
  4213.         (vars
  4214.          (list
  4215.           (cons 'c++-c-mode-syntax-table 'c-mode-syntaxt-table)
  4216.           (cons 'c++-tab-always-indent 'c-tab-always-indent)
  4217.           (cons 'c++-always-arglist-indent-p na)
  4218.           (cons 'c++-block-close-brace-offset 'c-offsets-alist)
  4219.           (cons 'c++-paren-as-block-close-p na)
  4220.           (cons 'c++-continued-member-init-offset 'c-offsets-alist)
  4221.           (cons 'c++-member-init-indent 'c-offsets-alist)
  4222.           (cons 'c++-friend-offset na)
  4223.           (cons 'c++-access-specifier-offset 'c-offsets-alist)
  4224.           (cons 'c++-empty-arglist-indent 'c-offsets-alist)
  4225.           (cons 'c++-comment-only-line-offset 'c-comment-only-line-offset)
  4226.           (cons 'c++-C-block-comments-indent-p 'c-block-comments-indent-p)
  4227.           (cons 'c++-cleanup-list 'c-cleanup-list)
  4228.           (cons 'c++-hanging-braces 'c-hanging-braces-alist)
  4229.           (cons 'c++-hanging-member-init-colon 'c-hanging-colons-alist)
  4230.           (cons 'c++-auto-hungry-initial-state
  4231.             "Use `c-auto-newline' and `c-hungry-delete-key' instead.")
  4232.           (cons 'c++-auto-hungry-toggle na)
  4233.           (cons 'c++-relative-offset-p na)
  4234.           (cons 'c++-special-indent-hook 'c-special-indent-hook)
  4235.           (cons 'c++-delete-function 'c-delete-function)
  4236.           (cons 'c++-electric-pound-behavior 'c-electric-pound-behavior)
  4237.           (cons 'c++-hungry-delete-key 'c-hungry-delete-key)
  4238.           (cons 'c++-auto-newline 'c-auto-newline)
  4239.           (cons 'c++-match-header-strongly na)
  4240.           (cons 'c++-defun-header-strong-struct-equivs na)
  4241.           (cons 'c++-version 'c-version)
  4242.           (cons 'c++-mode-help-address 'c-mode-help-address)
  4243.           (cons 'c-indent-level 'c-basic-offset)
  4244.           (cons 'c-brace-imaginary-offset na)
  4245.           (cons 'c-brace-offset 'c-offsets-alist)
  4246.           (cons 'c-argdecl-indent 'c-offsets-alist)
  4247.           (cons 'c-label-offset 'c-offsets-alist)
  4248.           (cons 'c-continued-statement-offset 'c-offsets-alist)
  4249.           (cons 'c-continued-brace-offset 'c-offsets-alist)
  4250.           (cons 'c-default-macroize-column 'c-backslash-column)
  4251.           (cons 'c++-default-macroize-column 'c-backslash-column)
  4252.           )))
  4253.        (mapcar
  4254.     (function
  4255.      (lambda (elt)
  4256.        (make-obsolete-variable (car elt) (cdr elt))))
  4257.     vars)))
  4258.  
  4259. (provide 'cc-mode)
  4260. ;;; cc-mode.el ends here
  4261.